什么是 - [NSString sizeWithFont:forWidth:lineBreakMode:]有用吗?

时间:2009-01-18 17:40:25

标签: iphone objective-c cocoa-touch

在我的问题“How do I get -[NSString sizeWithFont:forWidth:lineBreakMode:] to work?”中,我了解到-[NSString sizeWithFont:constrainedToSize:lineBreakMode:]实际上就是我所需要的。

-[NSString sizeWithFont:forWidth:lineBreakMode:]州的文档解释说它实际上并没有将文本包装到其他行。那我该如何使用呢? (例子会有所帮助。)

4 个答案:

答案 0 :(得分: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;

您可以指定放置文本的区域的大小,然后此方法会告诉您将占用多少空间(根据需要进行换行)。此外,如果字符串将溢出你提供的矩形的边界,你可以告诉然后决定如何显示文本。

对它的引用实际上并没有包装文本,因为这种方法实际上并没有对文本做任何事情。它实际上只是将它排除在外,并返回它需要多大的区域来实现它。

标签(或者您用于文本的容器)的责任是执行包装/需要做的其他事情。

希望有所帮助。

克里斯。

答案 1 :(得分:25)

有一段时间我以为这个例程就被打破了。这听起来像是一个完美的例行程序,用于解决如何一段文字,当以一定宽度包裹时。然而,这不是它的作用。实际上,返回的高度总是一行。 (顺便提一句,这是毫无意义的:UIFont的{​​{1}}返回相同的值。)

在撰写本文时引用文档:

  

虽然它计算了换行的位置,但这种方法实际上并没有将文本换行到其他行; [...]

这句话困扰了我很久。我的想法是:

  • 计算换行符,但不包装。是吗?
  • 也许他们的意思是接收-leading本身不会被改变以反映换行符?但我还是没想到呢?
  • 这句话与自己不一致。我别无选择,只能忽视它。

但事实证明,这与我们看到的行为相符。他们的意思似乎是:

  

此例程将计算第一个换行符的位置,并且为了计算边界框,将忽略此后的所有文本。

返回的边界框因此具有单行高度和最大指定宽度。 (根据计算换行符的位置,或者文本足够短以至于不需要最大宽度,宽度可能会更小。)

To,嗯,回答实际问题:有什么好处?我自己没有发现任何有用的东西:只有我认为有用的东西,但事实并非如此。然而,有些事情会浮现在脑海中:

  • 以单行文字为中心。我在这里想按钮和/或标题。 (虽然NSStringUILabel可以做到,但有时您想自己绘制它。)
  • 计算较长文本的“提取”的边界。在这里,我正在考虑你可能想要显示更大片段文本的片段。

答案 2 :(得分:2)

听起来对单线标签有好处。例如,如果您正在绘制可能被截断或具有换行符的字符串,但实际上您不会绘制多行。知道字符串的确切高度和宽度仍然有用,因此您可以将其准确定位在您想要的位置(并在其周围绘制其他UI项目)。

答案 3 :(得分: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]];然后重新定义视图的尺寸。您可以将此逻辑应用于任何视图,但它不会处理像Pajama那样的换行符。

虽然睡衣的答案适用于某些人,但它对我不起作用。这是一个详细的解释,如果你想要一个带有图像和可调整大小的UILabel的动态自定义MKAnnotation引脚,你应该在去其他地方之前立即尝试。