Adjust UILabel height depending on the text
Asked Answered
N

34

327

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.

Natachanatal answered 15/1, 2009 at 11:19 Comment(2)
See also: #406712Fleeta
Swift version down below: https://mcmap.net/q/23614/-adjust-uilabel-height-depending-on-the-textBrowder
G
417

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;
Gonophore answered 15/1, 2009 at 15:1 Comment(11)
This uses 9999, how would you do it flexible to the text?Gaiter
@Gaiter 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.Gonophore
Is there anyway to use a line break with this method?Ascertain
If you are sizing your labels like this, you are doing it wrong. You should use [label sizeToFit].Refinery
Don't forget that sizeWithFont is deprecated in iOS 7. #18898396Steeple
how to do this in swift please can someone help me with that ?Matrices
Use boundingRectWithSize insteadPreacher
deprecated. Update the answer pleaseWillard
Surely just use sizeThatFits instead of sizeWithFont? Just make sure to have set the UILabel's font first.Representational
How to do the same thing on swift?Cursed
@MariánČerný and @Representational 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.Crematorium
G
250

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];
Groundmass answered 20/8, 2009 at 4:45 Comment(9)
The size to fit was exactly what i needed to get the text to wrap, long with myUILabel.lineBreakMode = UILineBreakModeWordWrap; myUILabel.numberOfLines = 0;Budweis
A much easier solution than the answer marked as correct and works just as well.Canny
@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.Groundmass
@Donna.. I din't get your preferred with.. are you talking about its frame??Eliath
@DonnaLea, Thank you very much. your simple approach to the solution helped me to solve my problem too.Hersey
I had to reset the width before calling sizeToFit. [[cell textLabel] setFrame:CGRectMake(10, 10, 210, kCellMinHeight)]; [[cell textLabel] sizeToFit];Madaih
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.Jahn
What if I need to know the size?Allegra
@Allegra 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.Groundmass
P
46

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];
...
Poultice answered 4/11, 2013 at 21:14 Comment(0)
B
45

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.

Biscuit answered 26/4, 2016 at 10:52 Comment(4)
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"Buckboard
this needs to be marked as the correct answer. This is the right way with ib.Hierocracy
@SPQR3 whats the problem ? it helped to lot of people and its working fine.Biscuit
What exactly I'm looking for. Great job.Cutlass
M
41

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.
Morie answered 18/6, 2015 at 19:8 Comment(2)
This one works for UILabel embedded in a custom xib cell in a UITableView.Hoyle
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)Flourishing
K
16

Thanks guys for help, here is the code I tried which is working for me

   UILabel *instructions = [[UILabel alloc]initWithFrame:CGRectMake(10, 225, 300, 180)];
   NSString *text = @"First take clear picture and then try to zoom in to fit the ";
   instructions.text = text;
   instructions.textAlignment = UITextAlignmentCenter;
   instructions.lineBreakMode = NSLineBreakByWordWrapping;
   [instructions setTextColor:[UIColor grayColor]];

   CGSize expectedLabelSize = [text sizeWithFont:instructions.font 
                                constrainedToSize:instructions.frame.size
                                    lineBreakMode:UILineBreakModeWordWrap];

    CGRect newFrame = instructions.frame;
    newFrame.size.height = expectedLabelSize.height;
    instructions.frame = newFrame;
    instructions.numberOfLines = 0;
    [instructions sizeToFit];
    [self addSubview:instructions];
Keos answered 23/11, 2010 at 17:20 Comment(1)
sizeWithFont is deprecated.Fertility
P
12

Solution to iOS7 prior and iOS7 above

//
//  UILabel+DynamicHeight.m
//  For StackOverFlow
//
//  Created by Vijay on 24/02/14.
//  Copyright (c) 2014 http://Vijay-Apple-Dev.blogspot.com. All rights reserved.
//

#import <UIKit/UIKit.h>

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

#define SYSTEM_VERSION_LESS_THAN(v)                 ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

#define iOS7_0 @"7.0"

@interface UILabel (DynamicHeight)

/*====================================================================*/

/* Calculate the size,bounds,frame of the Multi line Label */

/*====================================================================*/
/**
 *  Returns the size of the Label
 *
 *  @param aLabel To be used to calculte the height
 *
 *  @return size of the Label
 */

-(CGSize)sizeOfMultiLineLabel;

@end


//
//  UILabel+DynamicHeight.m
//  For StackOverFlow
//
//  Created by Vijay on 24/02/14.
//  Copyright (c) 2014 http://Vijay-Apple-Dev.blogspot.com. All rights reserved.
//

#import "UILabel+DynamicHeight.h"

@implementation UILabel (DynamicHeight)
/*====================================================================*/

/* Calculate the size,bounds,frame of the Multi line Label */

/*====================================================================*/
/**
 *  Returns the size of the Label
 *
 *  @param aLabel To be used to calculte the height
 *
 *  @return size of the Label
 */
-(CGSize)sizeOfMultiLineLabel{

    NSAssert(self, @"UILabel was nil");

    //Label text
    NSString *aLabelTextString = [self text];

    //Label font
    UIFont *aLabelFont = [self font];

    //Width of the Label
    CGFloat aLabelSizeWidth = self.frame.size.width;


    if (SYSTEM_VERSION_LESS_THAN(iOS7_0)) {
        //version < 7.0

        return [aLabelTextString sizeWithFont:aLabelFont
                            constrainedToSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT)
                                lineBreakMode:NSLineBreakByWordWrapping];
    }
    else if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(iOS7_0)) {
        //version >= 7.0

        //Return the calculated size of the Label
        return [aLabelTextString boundingRectWithSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{
                                                        NSFontAttributeName : aLabelFont
                                                        }
                                              context:nil].size;

    }

    return [self bounds].size;

}

@end
Plymouth answered 24/2, 2014 at 10:16 Comment(3)
In UITableViewController's subclass, where should I call this method?Lovering
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 neededPlymouth
Vijay sizeWithFont is depricated.Sequestrate
W
11

Since sizeWithFont is deprecated I use this one instead.

this one get label specific attributes.

-(CGFloat)heightForLabel:(UILabel *)label withText:(NSString *)text{

    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName:label.font}];
    CGRect rect = [attributedText boundingRectWithSize:(CGSize){label.frame.size.width, CGFLOAT_MAX}
                                           options:NSStringDrawingUsesLineFragmentOrigin
                                           context:nil];

    return ceil(rect.size.height);
}
Wilfredwilfreda answered 13/11, 2014 at 23:40 Comment(0)
Y
10

UILabel extension based on this answer for Swift 4 and above

extension UILabel {

    func retrieveTextHeight () -> CGFloat {
        let attributedText = NSAttributedString(string: self.text!, attributes: [NSFontAttributeName:self.font])

        let rect = attributedText.boundingRect(with: CGSize(width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil)

        return ceil(rect.size.height)
    }

}

Can be used like:

self.labelHeightConstraint.constant = self.label.retrieveTextHeight()
Yul answered 31/10, 2017 at 13:0 Comment(0)
A
6

You can implement TableViewController's (UITableViewCell *)tableView:cellForRowAtIndexPath method in the following way (for example) :

#define CELL_LABEL_TAG 1

- (UITableViewCell *)tableView:(UITableView *)tableView  cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *text = @"my long text";

    static NSString *MyIdentifier = @"MyIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero  reuseIdentifier:identifier] autorelease];
    }

    CGFloat width = [UIScreen mainScreen].bounds.size.width - 50;
    CGFloat height = [self textHeight:text] + 10;
    CGRect frame = CGRectMake(10.0f, 10.0f, width, height);

    UILabel *cellLabel = [[UILabel alloc] initWithFrame:frame];
    cellLabel.tag = CELL_LABEL_TAG;
    cellLabel.textColor = [UIColor blackColor];
    cellLabel.backgroundColor = [UIColor clearColor];
    cellLabel.textAlignment = UITextAlignmentLeft;
    cellLabel.font = [UIFont systemFontOfSize:12.0f];
    [cell.contentView addSubview:cellLabel];
    [cellLabel release];

    return cell;
}

UILabel *label = (UILabel *)[cell viewWithTag:CELL_LABEL_TAG];
label.text = text;
label.numberOfLines = 0;
[label sizeToFit];
return cell;

Also use NSString's sizeWithFont:constrainedToSize:lineBreakMode: method to compute the text's height.

Arp answered 15/1, 2009 at 14:10 Comment(0)
T
6

Here is a category version:

UILabel+AutoSize.h #import

@interface UILabel (AutoSize)

- (void) autosizeForWidth: (int) width;

@end

UILabel+AutoSize.m

#import "UILabel+AutoSize.h"

@implementation UILabel (AutoSize)

- (void) autosizeForWidth: (int) width {
    self.lineBreakMode = UILineBreakModeWordWrap;
    self.numberOfLines = 0;
    CGSize maximumLabelSize = CGSizeMake(width, FLT_MAX);
    CGSize expectedLabelSize = [self.text sizeWithFont:self.font constrainedToSize:maximumLabelSize lineBreakMode:self.lineBreakMode];
    CGRect newFrame = self.frame;
    newFrame.size.height = expectedLabelSize.height;
    self.frame = newFrame;
}

@end
Theolatheologian answered 10/4, 2013 at 17:58 Comment(0)
F
5

My approach to compute the dynamic height of UILabel.

    let width = ... //< width of this label 
    let text = ... //< display content

    label.numberOfLines = 0
    label.lineBreakMode = .byWordWrapping
    label.preferredMaxLayoutWidth = width

    // Font of this label.
    //label.font = UIFont.systemFont(ofSize: 17.0)
    // Compute intrinsicContentSize based on font, and preferredMaxLayoutWidth
    label.invalidateIntrinsicContentSize() 
    // Destination height
    let height = label.intrinsicContentSize.height

Wrap to function:

func computeHeight(text: String, width: CGFloat) -> CGFloat {
    // A dummy label in order to compute dynamic height.
    let label = UILabel()

    label.numberOfLines = 0
    label.lineBreakMode = .byWordWrapping
    label.font = UIFont.systemFont(ofSize: 17.0)

    label.preferredMaxLayoutWidth = width
    label.text = text
    label.invalidateIntrinsicContentSize()

    let height = label.intrinsicContentSize.height
    return height
}
Fontana answered 19/7, 2017 at 6:2 Comment(0)
F
4

And for those that are migrating to iOS 8, here is a class extension for Swift:

extension UILabel {

    func autoresize() {
        if let textNSString: NSString = self.text {
            let rect = textNSString.boundingRectWithSize(CGSizeMake(self.frame.size.width, CGFloat.max),
                options: NSStringDrawingOptions.UsesLineFragmentOrigin,
                attributes: [NSFontAttributeName: self.font],
                context: nil)
            self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, rect.height)
        }
    }

}
Fen answered 27/8, 2014 at 9:18 Comment(0)
R
4

The easiest and better way that worked for me was to apply height constraint to label and set the priority to low, i.e., (250) in storyboard.

So you need not worry about calculating the height and width programmatically, thanks to storyboard.

Rovelli answered 16/5, 2016 at 16:43 Comment(0)
M
4

You can get height using below code

You have to pass

  1. text 2. font 3. label width

    func heightForLabel(text: String, font: UIFont, width: CGFloat) -> CGFloat {
    
       let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
       label.numberOfLines = 0
       label.lineBreakMode = NSLineBreakMode.byWordWrapping
       label.font = font
       label.text = text
       label.sizeToFit()
    
       return label.frame.height
    }
    
Marrowfat answered 12/4, 2018 at 10:43 Comment(0)
S
3

Updated Method

+ (CGFloat)heightForText:(NSString*)text font:(UIFont*)font withinWidth:(CGFloat)width {

    CGSize constraint = CGSizeMake(width, 20000.0f);
    CGSize size;

    CGSize boundingBox = [text boundingRectWithSize:constraint
                                                  options:NSStringDrawingUsesLineFragmentOrigin
                                               attributes:@{NSFontAttributeName:font}
                                                  context:nil].size;

    size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height));

    return size.height;
}
Schistosomiasis answered 6/7, 2015 at 12:21 Comment(0)
V
3

This is one line of code to get the UILabel Height using Objective-c:

labelObj.numberOfLines = 0;
CGSize neededSize = [labelObj sizeThatFits:CGSizeMake(screenWidth, CGFLOAT_MAX)];

and using .height you will get the height of label as follows:

neededSize.height
Valina answered 7/3, 2017 at 13:22 Comment(1)
Best current answer.Sadiras
K
2

Thanks for this post. It helped me a great deal. In my case I am also editing the text in a separate view controller. I noticed that when I use:

[cell.contentView addSubview:cellLabel];

in the tableView:cellForRowAtIndexPath: method that the label view was continually rendered over the top of the previous view each time I edited the cell. The text became pixelated, and when something was deleted or changed, the previous version was visible under the new version. Here's how I solved the problem:

if ([[cell.contentView subviews] count] > 0) {
    UIView *test = [[cell.contentView subviews] objectAtIndex:0];
    [test removeFromSuperview];
}
[cell.contentView insertSubview:cellLabel atIndex:0];

No more weird layering. If there is a better way to handle this, Please let me know.

Kamp answered 20/2, 2009 at 22:54 Comment(0)
C
2
UILabel *itemTitle = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 10,100, 200.0f)];
itemTitle.text = @"aseruy56uiytitfesh";
itemTitle.adjustsFontSizeToFitWidth = NO;
itemTitle.autoresizingMask = UIViewAutoresizingFlexibleWidth;
itemTitle.font = [UIFont boldSystemFontOfSize:18.0];
itemTitle.textColor = [UIColor blackColor];
itemTitle.shadowColor = [UIColor whiteColor];
itemTitle.shadowOffset = CGSizeMake(0, 1);
itemTitle.backgroundColor = [UIColor blueColor];
itemTitle.lineBreakMode = UILineBreakModeWordWrap;
itemTitle.numberOfLines = 0;
[itemTitle sizeToFit];
[self.view addSubview:itemTitle];

use this here all the properties are used on the label and test it by increasing the text in the itemTitle.text as

itemTitle.text = @"diofgorigjveghnhkvjteinughntivugenvitugnvkejrfgnvkhv";

it will show the perfetc answer as you need

Capwell answered 27/6, 2013 at 12:2 Comment(0)
H
2

You may use it as a method, as well. @Pyjamasam is very much true so i am just making its method. It may be helpfull for some one else

-(CGRect)setDynamicHeightForLabel:(UILabel*)_lbl andMaxWidth:(float)_width{
    CGSize maximumLabelSize = CGSizeMake(_width, FLT_MAX);

    CGSize expectedLabelSize = [_lbl.text sizeWithFont:_lbl.font constrainedToSize:maximumLabelSize lineBreakMode:_lbl.lineBreakMode];

    //adjust the label the the new height.
    CGRect newFrame = _lbl.frame;
    newFrame.size.height = expectedLabelSize.height;
    return newFrame;
}

and just set it like this

label.frame = [self setDynamicHeightForLabel:label andMaxWidth:300.0];
Holleran answered 20/1, 2014 at 12:19 Comment(0)
B
2

To do this in Swift3 following is the code:

 let labelSizeWithFixedWith = CGSize(width: 300, height: CGFloat.greatestFiniteMagnitude)
            let exactLabelsize = self.label.sizeThatFits(labelSizeWithFixedWith)
            self.label.frame = CGRect(origin: CGPoint(x: 20, y: 20), size: exactLabelsize)
Begat answered 1/3, 2017 at 13:27 Comment(0)
C
2

Adding to the above answers:

This can be easily achieved via storyboard.

  1. Set constraint for UILabel.(In my case I did top, left and fixed width)
  2. Set Number of line to 0 in Attribute Inspector
  3. Set Line Break to WordWrap in Attribute Inspector.

UILabel Height Adjust

Chalmer answered 18/10, 2017 at 22:10 Comment(0)
N
1

Finally, it worked. Thank you guys.

I was not getting it to work because i was trying to resize the label in heightForRowAtIndexPath method:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

and (yeah silly me), i was resizing the label to default in cellForRowAtIndexPath method - i was overlooking the code i had written earlier:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Natachanatal answered 16/1, 2009 at 7:25 Comment(0)
A
1

One line is Chris's answer is wrong.

newFrame.size.height = maximumLabelSize.height;

should be

newFrame.size.height = expectedLabelSize.height;

Other than that, it's the correct solution.

Andrej answered 21/5, 2009 at 6:31 Comment(0)
W
1
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cellIdentifier = @"myCell";
    cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    cell.myUILabel.lineBreakMode = UILineBreakModeWordWrap;        
    cell.myUILabel.numberOfLines = 0;
    cell.myUILabel.text = @"Some very very very very long text....."
    [cell.myUILabel.criterionDescriptionLabel sizeToFit];    
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
    CGFloat rowHeight = cell.myUILabel.frame.size.height + 10;

    return rowHeight;    
}
Wagtail answered 29/8, 2012 at 7:29 Comment(2)
Can you add some explanation to how your solution solves the OP's issue?Wart
you cannot ask UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; in heightForRowAtIndexPath, you will ge t and infinite loopGroundspeed
P
1
NSString *str = @"Please enter your text......";
CGSize lblSize = [str sizeWithFont:[UIFont systemFontOfSize:15] constrainedToSize: CGSizeMake(200.0f, 600.0f) lineBreakMode: NSLineBreakByWordWrapping];

UILabel *label = [[UILabel alloc]init];
label.frame = CGRectMake(60, 20, 200, lblSize.height);
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.font = [UIFont systemFontOfSize:15];
label.text = str;
label.backgroundColor = [UIColor clearColor];
[label sizeToFit];
[self.view addSubview:label];
Presnell answered 29/4, 2015 at 7:13 Comment(0)
E
1

My code:

UILabel *label      = [[UILabel alloc] init];
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.text          = text;
label.textAlignment = NSTextAlignmentCenter;
label.font          = [UIFont fontWithName:_bodyTextFontFamily size:_bodyFontSize];

CGSize size = [label sizeThatFits:CGSizeMake(width, MAXFLOAT)];


float height        = size.height;
label.frame         = CGRectMake(x, y, width, height);
Ep answered 8/6, 2015 at 6:51 Comment(0)
B
1

Swift 2:

    yourLabel.text = "your very long text"
    yourLabel.numberOfLines = 0
    yourLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
    yourLabel.frame.size.width = 200
    yourLabel.frame.size.height = CGFloat(MAXFLOAT)
    yourLabel.sizeToFit()

The interesting lines are sizeToFit() in conjunction with setting a frame.size.height to the max float, this will give room for long text, but sizeToFit() will force it to only use the necessary, but ALWAYS call it after setting the .frame.size.height .

I recommend setting a .backgroundColor for debug purposes, this way you can see the frame being rendered for each case.

Browder answered 26/11, 2015 at 18:51 Comment(2)
yourLabel.frame.height is a get only propertyFavrot
yourLabel.frame.size.width and yourLabel.frame.size.height are read only as wellJosejosee
L
1

This method will give perfect height

-(float) getHeightForText:(NSString*) text withFont:(UIFont*) font andWidth:(float) width{
CGSize constraint = CGSizeMake(width , 20000.0f);
CGSize title_size;
float totalHeight;


title_size = [text boundingRectWithSize:constraint
                                options:NSStringDrawingUsesLineFragmentOrigin
                             attributes:@{ NSFontAttributeName : font }
                                context:nil].size;

totalHeight = ceil(title_size.height);

CGFloat height = MAX(totalHeight, 40.0f);
return height;
}
Lanham answered 7/4, 2016 at 14:0 Comment(1)
Do not copy content from elsewhere without clear attribution. It is seen as plagiarism. See stackoverflow.com/help/referencing (https://mcmap.net/q/23652/-change-the-height-of-uilabel-dynamically-based-on-content).Amharic
P
1
myLabel.text = "your very long text"
myLabel.numberOfLines = 0
myLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping

Please set constraints for UILable in storyboard including top left bottom right

Politick answered 21/1, 2017 at 9:7 Comment(0)
B
0

This method will work for both iOS 6 and 7

- (float)heightForLabelSize:(CGSize)maximumLabelSize  Font:(UIFont *)font String:(NSString*)string {

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:font forKey: NSFontAttributeName];

    CGSize adjustedLabelSize = [string maximumLabelSize
                                                                  options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin
                                                               attributes:stringAttributes context:nil].size;
    return adjustedLabelSize.height;
}
else {
    CGSize adjustedLabelSize = [string sizeWithFont:font constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping];

    return adjustedLabelSize.height;
}

}
Barrie answered 17/1, 2014 at 14:55 Comment(0)
U
0

Problem is that none of mentioned functions is realiable and for some string and font will return incorrect height value. Especially will fail for attributed texts.

The only realiable solution is here: https://mcmap.net/q/23653/-core-text-39-s-ctframesettersuggestframesizewithconstraints-returns-incorrect-size-every-time and the point is to use CoreText to manually calculate height of every line to get right size. There is no other known way to do this.

Unwrap answered 28/1, 2014 at 8:55 Comment(0)
A
-2

Updates according iOS7

// If description are available for protocol
protocolDescriptionLabel.text = [dataDictionary objectForKey:@"description"];
[protocolDescriptionLabel sizeToFit];
[protocolDescriptionLabel setLineBreakMode:NSLineBreakByWordWrapping];

CGSize expectedLabelSize = [protocolDescriptionLabel
               textRectForBounds:protocolDescriptionLabel.frame
               limitedToNumberOfLines:protocolDescriptionLabel.numberOfLines].size;
NSLog(@"expectedLabelSize %f", expectedLabelSize.height);

//adjust the label the the new height.
CGRect newFrame = protocolDescriptionLabel.frame;
newFrame.size.height = expectedLabelSize.height;
protocolDescriptionLabel.frame = newFrame;
Ament answered 13/11, 2013 at 7:51 Comment(0)
C
-3

When autoLayout is enabled the resizing doesn't work :)

Catinacation answered 9/10, 2013 at 2:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.