147

I want to display an image next to a UILabel, however UILabel has variable text length, so I don't know where to place the image. How can I accomplish this?

Jakub Truhlář
  • 20,070
  • 9
  • 74
  • 84
Sheehan Alam
  • 60,111
  • 124
  • 355
  • 556

8 Answers8

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

What is -[NSString sizeWithFont:forWidth:lineBreakMode:] good for?

this question might have your answer, it worked for me.


For 2014, I edited in this new version, based on the ultra-handy comment by Norbert below! This does everything.

// 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);
starball
  • 20,030
  • 7
  • 43
  • 238
Aaron Saunders
  • 33,180
  • 5
  • 60
  • 80
  • 41
    Just a note: this is deprecated since iOS7. The preferred way now is: `[yourString boundingRectWithSize:maximumLabelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName:yourLabel.font } context:nil];` – Norbert Nov 17 '13 at 14:40
  • 17
    You can also use the IntrinsicContentSize property. I'm not much into Objective-c, but it should be something like this: `self.yourLabel.intrinsicContentSize` This will give you the size of the label content, so you can just get the width from there. – Boris Jul 22 '14 at 08:27
  • 1
    Just `yourLabel.intrinsicContentSize.width` works great, check answer below. – denis_lor Jun 06 '19 at 12:58
168

yourLabel.intrinsicContentSize.width for Objective-C / Swift

Jakub Truhlář
  • 20,070
  • 9
  • 74
  • 84
  • 1
    not work for me it is not calculating label's width height on the basis of their text – Chandni May 27 '18 at 12:06
  • 2
    Works perfectly for me, with custom font also! – heyfrank Sep 19 '18 at 10:42
  • 2
    perfect answer for getting width of dynamic label – Chetan Jan 27 '20 at 10:32
  • My use case: I set a constant width for trailing labels several rows, in a UIView, such that the start of the text in each label would line up for those rows. In Autolayout I wanted to append label 3px past end of the text in each row, but setting lead anchor of item to trailing anchor of label, put the item off screen to right. But setting lead anchor of the item to *lead* anchor of label + (label intrinsic content size + 3) made item hug the *text* content perfectly. Excellent!!! – clearlight Mar 06 '23 at 11:03
53

In swift

 yourLabel.intrinsicContentSize().width 
Arshad
  • 906
  • 7
  • 12
33

The selected answer is correct for iOS 6 and below.

In iOS 7, sizeWithFont:constrainedToSize:lineBreakMode: has been deprecated. It is now recommended you use boundingRectWithSize:options:attributes:context:.

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

Note that the return value is a CGRect not a CGSize. Hopefully that'll be of some assistance to people using it in iOS 7.

Chetan Shenoy
  • 843
  • 1
  • 10
  • 19
18

Swift 4 Answer who are using Constraint

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 Answer who are using Constraint

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
iOS Lifee
  • 2,091
  • 23
  • 32
  • 2
    Great! Convenient for calculating the width of UIButton according to text, where intrinsicContentSize.width doesn't always work correctly. – nomnom Aug 05 '19 at 11:00
13

In iOS8 sizeWithFont has been deprecated, please refer to

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

You can add all the attributes you want in sizeWithAttributes. Other attributes you can set:

- NSForegroundColorAttributeName
- NSParagraphStyleAttributeName
- NSBackgroundColorAttributeName
- NSShadowAttributeName

and so on. But probably you won't need the others

jarora
  • 5,384
  • 2
  • 34
  • 46
8
CGRect rect = label.frame;
rect.size = [label.text sizeWithAttributes:@{NSFontAttributeName : [UIFont fontWithName:label.font.fontName size:label.font.pointSize]}];
label.frame = rect;
Kampai
  • 22,848
  • 21
  • 95
  • 95
Honey Lakhani
  • 83
  • 1
  • 7
  • 2
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient [reputation](http://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](http://stackoverflow.com/help/privileges/comment). – The Humble Rat Aug 07 '15 at 09:18
  • this answer tell how to adjust label size according to text. whats the problem in this? – Honey Lakhani Aug 07 '15 at 09:28
2

Here's something I came up with after applying a few principles other SO posts, including Aaron's link:

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];

In this example, I'm adding a custom pin to a MKAnnotation class that resizes a UILabel according to the text size. It also adds an image on the left side of the view, so you see some of the code managing the proper spacing to handle the image and padding.

The key is to use CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]]; and then redefine the view's dimensions. You can apply this logic to any view.

Although Aaron's answer works for some, it didn't work for me. This is a far more detailed explanation that you should try immediately before going anywhere else if you want a more dynamic view with an image and resizable UILabel. I already did all the work for you!!

aturan23
  • 4,798
  • 4
  • 28
  • 52
whyoz
  • 5,168
  • 47
  • 53