“-[NSString sizeWithFont:forWidth:lineBreakMode:]”有什么用?它与编程有关。

38
在我的问题“如何让-[NSString sizeWithFont:forWidth:lineBreakMode:]工作?”中,我了解到实际上我需要使用-[NSString sizeWithFont:constrainedToSize:lineBreakMode:]-[NSString sizeWithFont:forWidth:lineBreakMode:]的文档说明它实际上不会将文本换行到额外的行。那么我该如何使用它呢?(举例会更好)
4个回答

66

它同样适用于多行字符串。

基本上,这是一个函数,让你可以看到使用特定字体和换行模式渲染一个字符串时将会有多大。

我在应用程序中的一些区域中使用它,当我有变长文本需要显示时。

默认情况下,UILabel 将文本垂直居中。如果要使文本顶部对齐,则需要将标签大小设置为仅包含其中的字符串所需的高度。

我使用这种方法来实现。

以下是我使用示例:

//Calculate the expected size based on the font and linebreak mode of your label
CGSize maximumLabelSize = CGSizeMake(296,9999);

CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font 
                        constrainedToSize:maximumLabelSize 
                        lineBreakMode:yourLabel.lineBreakMode]; 

//adjust the label the the new height.
CGRect newFrame = yourLabel.frame;
newFrame.size.height = expectedLabelSize.height;
yourLabel.frame = newFrame;
您指定文本所需放置的区域大小,然后此方法会告诉您它需要多少空间(根据需要进行换行)。同时,如果字符串将超出您提供的矩形边界,则可以检测并决定如何显示文本。该方法未实际执行文本换行操作,只是虚拟布局并返回真正布局所需的区域大小。对于文本的换行/其他操作等需由标签(或您用于文本的任何容器)负责执行。

newFrame.size.height = maximumLabelSize.height; SB: newFrame.size.height = expectedLabelSize.height; - JoBu1324

25
有一段时间我以为这个例程是有问题的,听起来它似乎是用于计算在特定宽度下文本内容的高度时的完美例程。然而,实际情况并非如此。事实上,返回的高度始终只有一行。(顺便说一句,这是没有意义的: UIFont-leading 返回相同的值。)
引用当时的文档:
虽然它会计算换行的位置,但是这个方法实际上并不会将文本包装到额外的行中;
这句话让我困惑了很长时间。我的想法是:
计算了换行符,但是没有进行换行?嗯?
也许他们的意思是接收的 NSString 本身不会被改变以反映出换行符?但是我也不指望那样做。
这句话本身就不连贯。我别无选择,只能忽略它。
不过,后来发现有一个与我们看到的行为相匹配的含义。看起来他们的意思是:
这个例程将计算出第一个换行符出现的位置,并且所有在它之后的文本都不会被考虑在内以计算边界框。
因此,返回的边界框将具有单行高度和最大指定宽度的宽度。(宽度可能会因计算出的换行位置或文本太短而小于最大宽度。)
那么,回答实际问题:它有什么实际用途呢?我自己并没有找到任何有用的东西:只是我认为它会很有用的事情,但事实并非如此。然而,一些想到的东西包括:
使单行文本居中。我在考虑按钮和/或标题。(虽然 UILabelUIButton 可以做到这一点,但有时您想自己绘制。)
  • 计算长篇文本的“摘录”边界。这里我考虑的是当你想要展示一段更长的文本片段时可能需要的操作。

  • 2
    对于那个毫不客气的问题“它有什么用?”给个赞,我也曾有同样的想法。无论如何,听起来像是我需要使用NSString sizeWithFont:constrainedToSize:lineBreakMode。谢谢。 - Chris

    2

    听起来这对于单行标签会很有用。比如,如果你要绘制的字符串可能被截断或者换行,但实际上你只会绘制一行。知道字符串的确切高度和宽度仍然很有帮助,这样你就可以将其精确地定位在所需位置(并在其周围绘制其他UI元素)。


    1

    在应用了PyjamaSam示例中的几个原则后,我想到了这个东西:

    AnnotationPin *myAnnotation = (AnnotationPin *)annotation;
    
    self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier];
    self.backgroundColor = [UIColor greenColor];
    self.frame = CGRectMake(0,0,30,30);
    imageView = [[UIImageView alloc] initWithImage:myAnnotation.THEIMAGE];
    imageView.frame = CGRectMake(3,3,20,20);
    imageView.layer.masksToBounds = NO;
    [self addSubview:imageView];
    [imageView release];
    
    CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]];
    CGRect newFrame = self.frame;
    newFrame.size.height = titleSize.height + 12;
    newFrame.size.width = titleSize.width + 32;
    self.frame = newFrame;
    self.layer.borderColor = [UIColor colorWithRed:0 green:.3 blue:0 alpha:1.0f].CGColor;
    self.layer.borderWidth = 3.0;
    
    UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(26,5,newFrame.size.width-32,newFrame.size.height-12)];
    infoLabel.text = myAnnotation.title;
    infoLabel.backgroundColor = [UIColor clearColor];
    infoLabel.textColor = [UIColor blackColor];
    infoLabel.textAlignment = UITextAlignmentCenter;
    infoLabel.font = [UIFont systemFontOfSize:12];
    
    [self addSubview:infoLabel];
    [infoLabel release];
    

    在这个例子中,我正在向MKAnnotation类添加自定义标记,该标记根据文本大小调整UILabel的大小。它还在视图的左侧添加了一个图像,因此您可以看到一些代码来管理适当的间距以处理图像和填充。
    关键是使用CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]]; 然后重新定义视图的尺寸。您可以将此逻辑应用于任何视图,但它不像Pyjama's那样处理换行符。
    尽管Pyjama的答案对某些人有效,但对我无效。这是一个详细的解释,如果您想要具有图像和可调整大小的UILabel的动态自定义MKAnnotation标记,则应立即尝试。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接