如何根据文本长度计算UILabel的宽度?

147

我想在一个UILabel旁边显示一张图片,但是UILabel的文本长度是可变的,所以我不知道应该把图片放到哪里。如何实现这个功能?

8个回答

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

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

这个问题可能有你需要的答案,对我很有用。


针对2014年,我根据下面Norbert非常有用的评论编辑了这个新版本!它可以完成所有任务。

// yourLabel is your UILabel.

float widthIs = 
 [self.yourLabel.text
  boundingRectWithSize:self.yourLabel.frame.size                                           
  options:NSStringDrawingUsesLineFragmentOrigin
  attributes:@{ NSFontAttributeName:self.yourLabel.font }
  context:nil]
   .size.width;

NSLog(@"the width of yourLabel is %f", widthIs);

41
注意:自iOS7以来,此方法已被废弃。现在的首选方法是:[yourString boundingRectWithSize:maximumLabelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName:yourLabel.font } context:nil]; - Norbert
17
你还可以使用IntrinsicContentSize属性。我对Objective-C不是很熟悉,但应该像这样: self.yourLabel.intrinsicContentSize这将给出标签内容的大小,因此您可以从中获取宽度。 - Boris
1
只需使用 yourLabel.intrinsicContentSize.width 即可,查看下面的答案。 - denis_lor

168

Objective-C / SwiftyourLabel.intrinsicContentSize.width 的含义。


1
对我来说不起作用,它没有根据标签的文本计算其宽度和高度。 - Chandni
2
对我来说完美运行,还可以使用自定义字体! - heyfrank
2
获取动态标签宽度的完美解决方案 - Chetan
我的用例:在一个UIView中,我为几行尾部标签设置了一个恒定的宽度,以使每个标签中的文本起始位置排成一行。在自动布局中,我希望将标签附加到每行文本的末尾3px,但将项的前导锚点设置为标签的后续锚点会将该项放到屏幕右侧。但是,将项目的前导锚点设置为标签的前导锚点+(标签内部内容大小+3)可以完美地贴合文本内容。太棒了! - clearlight

53

在 Swift 中

 yourLabel.intrinsicContentSize().width 

12
这个答案仅适用于已经布局好的视图。 - rommex
1
XCode 不喜欢那些括号。 - John Pitts

33

所选答案适用于iOS 6及以下版本。

在iOS 7中,sizeWithFont:constrainedToSize:lineBreakMode:已经弃用。现在建议您使用boundingRectWithSize:options:attributes:context:

CGRect expectedLabelSize = [yourString boundingRectWithSize:sizeOfRect
                                                    options:<NSStringDrawingOptions>
                                                 attributes:@{
                                                    NSFontAttributeName: yourString.font
                                                    AnyOtherAttributes: valuesForAttributes
                                                 }
                                                    context:(NSStringDrawingContext *)];

请注意返回值是CGRect而不是CGSize。希望这对在iOS 7中使用它的人有所帮助。


18

使用约束条件的Swift 4答案

label.text = "Hello World"

var rect: CGRect = label.frame //get frame of label
rect.size = (label.text?.size(attributes: [NSFontAttributeName: UIFont(name: label.font.fontName , size: label.font.pointSize)!]))! //Calculate as per label font
labelWidth.constant = rect.width // set width to Constraint outlet

使用约束的人的 Swift 5 答案

label.text = "Hello World"

var rect: CGRect = label.frame //get frame of label
rect.size = (label.text?.size(withAttributes: [NSAttributedString.Key.font: UIFont(name: label.font.fontName , size: label.font.pointSize)!]))! //Calculate as per label font
labelWidth.constant = rect.width // set width to Constraint outlet

2
太好了!根据文本计算UIButton的宽度非常方便,其中intrinsicContentSize.width并不总是正确工作。 - nomnom

13

iOS8中已弃用sizeWithFont,请参考

CGSize yourLabelSize = [yourLabel.text sizeWithAttributes:@{NSFontAttributeName : [UIFont fontWithName:yourLabel.font size:yourLabel.fontSize]}];

您可以在 sizeWithAttributes 中添加所需的所有属性。 其他可设置的属性:

- NSForegroundColorAttributeName
- NSParagraphStyleAttributeName
- NSBackgroundColorAttributeName
- NSShadowAttributeName

等等,但你可能不需要其他的了。


8
CGRect rect = label.frame;
rect.size = [label.text sizeWithAttributes:@{NSFontAttributeName : [UIFont fontWithName:label.font.fontName size:label.font.pointSize]}];
label.frame = rect;

2
这并没有提供问题的答案。如果要批评或请求作者澄清,请在他们的帖子下留言 - 您始终可以在自己的帖子上发表评论,并且一旦您拥有足够的声望,您将能够评论任何帖子 - The Humble Rat
这个答案告诉了如何根据文本调整标签大小。有什么问题吗? - Honey Lakhani

2

在应用了一些其他SO帖子的原则之后,包括亚伦的链接后,我想到了这个:

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]];,然后重新定义视图的尺寸。您可以将此逻辑应用于任何视图。
虽然Aaron的答案对某些人有效,但对我不起作用。如果您想要具有图像和可调整大小的UILabel的更动态视图,则应立即尝试此更详细的解释。我已经为您完成了所有工作!

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