确定特定CGSize的UIFont的pointSize

Bar*_*rtu 1 cocoa-touch objective-c frame uilabel ios

我有一个具体CGSizeUILabel,我不能扩展框架,UILabel因为它是一个多行UILabels adjustsFontSizeToFitWidth方法不起作用.

所以我想我应该创建一个看起来像这样的功能;

- (CGFloat)fontSizeWithText:(NSString*)text andFont:(UIFont*)font constrainedSize:(CGSize)size LBM:(UILineBreakMode)LBM
{
    // check if text fits to label
    CGSize labelSize = [text sizeWithFont:font constrainedToSize:CGSizeMake(size.width, 9999) lineBreakMode:LBM];

    // if not, decrease font size until it fits to the given size
    while (labelSize.height > size.height) {
        font = [UIFont fontWithName:font.fontName size:font.pointSize - 0.5];
        labelSize = [text sizeWithFont:font constrainedToSize:CGSizeMake(size.width, 9999) lineBreakMode:LBM];
    }

    return font.pointSize;
}
Run Code Online (Sandbox Code Playgroud)

用法:

// fit detail label by arranging font's size
    CGFloat fontSize = [self fontSizeWithText:self.titleLabel.text andFont:self.titleLabel.font constrainedSize:self.titleLabel.frame.size LBM:self.titleLabel.lineBreakMode];
    self.titleLabel.font = [UIFont fontWithName:self.titleLabel.font.fontName size:fontSize];
Run Code Online (Sandbox Code Playgroud)

但是通过这种方法,我发现我的一些文本不适合UILabel的框架并被截断.必须有一些我缺少的东西.任何有关代码的帮助或任何其他有关解决"使用给定字体将文本拟合到特定多行UILabel"的建议都会很棒.

Tom*_*cks 6

首先让我们快速看一下整个问题.您正在尝试将文本放入预定义的框架中并调整字体大小.这通常不会很好地工作,因为即使在视网膜显示器上,您也会快速达到FAR太小而无法读取的尺寸.您应该调整标签的框架以容纳多余的文本(如果可能的话.有时,截断是唯一的选择.)

既然如此,那就让我们来看看调整字体大小.尽管不推荐它,我仍然会解释如何最好地解决它.

重要的是,此代码未经测试,很可能需要进行一些调整,但这可能是读者的练习.

所以我们首先需要知道的是一条线的高度.现在,我们有标签的高度和它可以显示的行数,因此我们可以通过简单地将标签高度除以行数来确定.

CGFloat optimalLineHeight = CGRectGetHeight(label.frame) / label.numberOfLines;
Run Code Online (Sandbox Code Playgroud)

您可能已经注意到,这可能会返回比实际需要更高的行.您将能够实现其他检查和约束来处理此问题.目前,字体大小也可以增长,而不仅仅是收缩.

现在,获得最佳线高只是故事的一部分.我们现在需要优化字体大小.这是一些代码:

CGFloat optimumFontSize = 0.0;
BOOL optimumFontSizeFound = NO;
do {
    CGSize charSize = [@"M" sizeWithFont:[UIFont systemFontOfSize:optimumFontSize]
                       constrainedToSize:CGSizeMake(100, 9999)
                           lineBreakMode:0];
    if ( CGSizeGetHeight(charSize) > optimalLineHeight ) {
        optimumFontSizeFound = YES;
    }
    else {
        optimumFontSize++;
    }
} while ( !optimumFontSizeFound );
Run Code Online (Sandbox Code Playgroud)

那这是做什么的呢?在这里,我们记录到目前为止最佳的FontSize.我们从假设字体大小为0开始,我们看到使用该字体大小的单个字符有多高.如果该高度大于先前计算的最佳线高,则先前的高度是最佳高度.如果没有,我们会增加尺寸并重复,直到找到最佳尺寸.

在这方面仍有许多问题需要克服,以使其在所有情况下都能完美运行.这确保您不会看到可见的垂直剪切字符,但无法确保所有文本内容都将显示在框架中.要做到这一点,你需要更加智能地确定所需的行数,但我将把它作为读者的练习.

希望这可以帮助您实现目标.