Adjust UILabel height depending on the text

291,036

Solution 1

sizeWithFont constrainedToSize:lineBreakMode: is the method to use. An example of how to use it is below:

//Calculate the expected size based on the font and linebreak mode of your label
// FLT_MAX here simply means no constraint in height
CGSize maximumLabelSize = CGSizeMake(296, FLT_MAX);

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;

Solution 2

You were going in the right direction. All you need to do is:

myUILabel.numberOfLines = 0;
myUILabel.text = @"Enter large amount of text here";
[myUILabel sizeToFit];

Solution 3

In iOS 6 Apple has added a property to UILabel that greatly simplifies dynamic vertical resizing of labels: preferredMaxLayoutWidth.

Using this property in combination with lineBreakMode = NSLineBreakByWordWrapping and sizeToFit method allows easily resize a UILabel instance to the height that accommodates the entire text.

A quote from iOS documentation:

preferredMaxLayoutWidth The preferred maximum width (in points) for a multiline label.

Discussion This property affects the size of the label when layout constraints are applied to it. During layout, if the text extends beyond the width specified by this property, the additional text is flowed to one or more new lines, thereby increasing the height of the label.

A sample:

...
UILabel *status = [[UILabel alloc] init];
status.lineBreakMode = NSLineBreakByWordWrapping;
status.numberOfLines = 5; // limits to 5 lines; use 0 for unlimited.

[self addSubview:status]; // self here is the parent view

status.preferredMaxLayoutWidth = self.frame.size.width; // assumes the parent view has its frame already set.

status.text = @"Some quite lengthy message may go here…";
[status sizeToFit];
[status setNeedsDisplay];
...

Solution 4

Check this work perfectly without adding Single line of code. (Using Autolayout)

I made a demo for you according to your requirement. Download it from below link,

Autoresize UIView and UILabel

Step by Step Guide :-

Step 1 :- Set constrain to UIView

1) Leading 2) Top 3) Trailing (From mainview)

enter image description here

Step 2 :- Set constrain to Label 1

1) Leading 2) Top 3) Trailing (From it's superview)

enter image description here

Step 3 :- Set constrain to Label 2

1) Leading 2) Trailing (From it's superview)

enter image description here

Step 4 :- Most tricky give botton to UILabel from UIView .

enter image description here

Step 5 :- (Optional) Set constrain to UIButton

1) Leading 2) Bottom 3) Trailing 4) Fixed Height (From mainview)

enter image description here

Output :-

enter image description here

Note :- Make sure you have set Number of lines =0 in Label property.

enter image description here

I hope this info enough to understand Autoresize UIView according to UILabel's height and Autoresize UILabel According to text.

Solution 5

Instead doing this programmatically, you can do this in Storyboard/XIB while designing.

  • Set UIlabel's number of lines property to 0 in attribute inspector.
  • Then set width constraint/(or) leading and trailing constraint as per the requirement.
  • Then set height constraint with minimum value. Finally select the height constraint you added and in the size inspector the one next to attribute inspector, change the height constraint's relation from equal to - greater than.
Share:
291,036
Mustafa
Author by

Mustafa

I'm a Manager Development/Project Manager/Team Lead/Mobile Application Developer located in Islamabad, Pakistan, working for BroadPeak Technologies. I'm currently focusing on managing and developing mobile applications for Android and iOS devices; with hands on experience developing iOS applications. More information.

Updated on September 11, 2020

Comments

  • Mustafa
    Mustafa over 3 years

    Consider I have the following text in a UILabel (a long line of dynamic text):

    Since the alien army vastly outnumbers the team, players must use the post-apocalyptic world to their advantage, such as seeking cover behind dumpsters, pillars, cars, rubble, and other objects.

    I want to resize the UILabel's height so that the text can fit in. I'm using following properties of UILabel to make the text within to wrap.

    myUILabel.lineBreakMode = UILineBreakModeWordWrap;
    myUILabel.numberOfLines = 0;
    

    Please let me know if I'm not heading in the right direction. Thanks.

  • Jack BeNimble
    Jack BeNimble about 13 years
    The size to fit was exactly what i needed to get the text to wrap, long with myUILabel.lineBreakMode = UILineBreakModeWordWrap; myUILabel.numberOfLines = 0;
  • memmons
    memmons about 13 years
    A much easier solution than the answer marked as correct and works just as well.
  • DonnaLea
    DonnaLea almost 13 years
    @Inder Kumar Rathore - I use this for multiple lines, all the time, hence the numberOfLines = 0; I guess it's missing setting the preffered width first, but I assumed that had already been done with the init of the UILabel.
  • Inder Kumar Rathore
    Inder Kumar Rathore almost 13 years
    @Donna.. I din't get your preferred with.. are you talking about its frame??
  • Naved
    Naved over 12 years
    @DonnaLea, Thank you very much. your simple approach to the solution helped me to solve my problem too.
  • quantumpotato
    quantumpotato about 12 years
    This uses 9999, how would you do it flexible to the text?
  • PyjamaSam
    PyjamaSam about 12 years
    @quantumpotato 9999 is just a place holder for the maximum space the text is allowed to take up. You can use any number there that works for your UI.
  • Sami
    Sami over 11 years
    Is there anyway to use a line break with this method?
  • Admin
    Admin over 11 years
    Can you add some explanation to how your solution solves the OP's issue?
  • Marián Černý
    Marián Černý about 11 years
    If you are sizing your labels like this, you are doing it wrong. You should use [label sizeToFit].
  • Peter Lapisu
    Peter Lapisu about 11 years
    you cannot ask UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; in heightForRowAtIndexPath, you will ge t and infinite loop
  • David Douglas
    David Douglas almost 11 years
    I had to reset the width before calling sizeToFit. [[cell textLabel] setFrame:CGRectMake(10, 10, 210, kCellMinHeight)]; [[cell textLabel] sizeToFit];
  • LightningStryk
    LightningStryk almost 11 years
    This does not work for me. I had an issue where sizeToFit was adjusting the width as well as the height and was causing my label to shrink.
  • attomos
    attomos over 10 years
    Don't forget that sizeWithFont is deprecated in iOS 7. stackoverflow.com/questions/18897896/…
  • Homam
    Homam about 10 years
    In UITableViewController's subclass, where should I call this method?
  • Vijay-Apple-Dev.blogspot.com
    Vijay-Apple-Dev.blogspot.com about 10 years
    Where you want to calculate the label height then call this method. then adjust the height of the table view. where you have tableview height for row at index method. calculate all vertical labels text as u needed
  • msmq
    msmq almost 9 years
    sizeWithFont is deprecated.
  • Developer
    Developer about 8 years
    What if I need to know the size?
  • DonnaLea
    DonnaLea about 8 years
    @Developer you can query the frame after you've called sizeToFit. But if you need to know the size, this might not be the right approach for you either.
  • Phil Hudson
    Phil Hudson about 8 years
    yourLabel.frame.height is a get only property
  • Matt
    Matt about 8 years
    Do not copy content from elsewhere without clear attribution. It is seen as plagiarism. See stackoverflow.com/help/referencing (stackoverflow.com/a/25158206/444991).
  • Kamal Upasena
    Kamal Upasena almost 8 years
    how to do this in swift please can someone help me with that ?
  • Viktor Malyi
    Viktor Malyi over 7 years
    Use boundingRectWithSize instead
  • CalZone
    CalZone over 7 years
    yourLabel.frame.size.width and yourLabel.frame.size.height are read only as well
  • Vyachaslav Gerchicov
    Vyachaslav Gerchicov about 7 years
    deprecated. Update the answer please
  • Leon
    Leon over 6 years
    Surely just use sizeThatFits instead of sizeWithFont? Just make sure to have set the UILabel's font first.
  • user3182143
    user3182143 over 6 years
    Vijay sizeWithFont is depricated.
  • Bogdan Razvan
    Bogdan Razvan almost 6 years
    And what if you would want to also have some views under the white-background view? Not giving it a height will show some red lines in SB for "Need constrains for: Y position or height"
  • Amg91
    Amg91 over 5 years
    How to do the same thing on swift?
  • Rana Tallal
    Rana Tallal about 5 years
    this needs to be marked as the correct answer. This is the right way with ib.
  • Gang Fang
    Gang Fang about 5 years
    This one works for UILabel embedded in a custom xib cell in a UITableView.
  • Badal Shah
    Badal Shah over 4 years
    @SPQR3 whats the problem ? it helped to lot of people and its working fine.
  • Mike
    Mike over 4 years
    Best current answer.
  • Le Mot Juiced
    Le Mot Juiced about 4 years
    @MariánČerný and @Leon sizeToFit and sizeThatFits don't fit the needs of the person posting, unless I'm misunderstanding. Both those methods adjust both width and height--the person wants a fixed with, and fixed font size and line break mode, and then to find the height that fits those.
  • Hamid Reza Ansari
    Hamid Reza Ansari about 4 years
    According to your answer i set a constant height to my label and set that priority to Low (250) and errors disappear . (Don't need to set equal to - greater than)
  • thevikasnayak
    thevikasnayak about 2 years
    What exactly I'm looking for. Great job.