Search code examples
iosstoryboarduilabel

Expand Label vertically based on quantity of text using Storyboard


I have a UIlabel linked to a property that can contain text of many different possible lengths.

How can I get the label to expand vertically to accommodate different quantities of text?

I have set lines to 0 in storyboard. And I've experimented with different heights in the Size Inspector. If I make the height large enough, the second line will display. But then if there is only one line, it leaves a lot of blank space. If the label is only about the size of one line, I am only seeing one line of text that ends at edge of label.

I have also tried the following code but it is not having the desired effect.

self.myLabel.numberOfLines = 0;
    [self.myLabel sizeToFit];

Would prefer not to use auto layout if possible unless there is no other way.


Solution

  • You might try the following piece of code. I'm not sure about your UI configuration but the code usually works:

    self.myLabel.numberOfLines = 0;
    self.myLabel.lineBreakMode = NSLineBreakByWordWrapping;
    self.myLabel.text = @"your long text";
    CGSize maxSize = CGSizeMake(200.0f, CGFLOAT_MAX); // you might change 200.0 to whatever suits for you
    
    CGSize requiredSize = [self.myLabel sizeThatFits:maxSize];
    //with Auto Layout you need to use: CGSize requiredSize = [self.myLabel systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    
    self.myLabel.frame = CGRectMake(self.myLabel.frame.origin.x, self.myLabel.frame.origin.y, requiredSize.width, requiredSize.height); //use whatever left/top you find suitable
    

    Edit

    If you want the below code to work expectedly, you must stick to Autoresizing not Auto Layout as you might have preferred.

    Picture 1 below, shows the checkbox you must uncheck to enable Autoresizing instead of Auto Layout.

    Then you need to reconsider the autoresizing masks applied to the label. You might set the autoresizing masks UIViewAutoresizingFlexibleLeftMargin and UIViewAutoresizingFlexibleTopMargin and absolutely nothing else. Please see the Picture 2 below:

    Auto layout

    Autoresizing masks

    Once you have set the autoresizing masks, create a method like following in your viewcontroller class:

    -(void)adjustLabelWithText:(NSString*)text {
        self.myLabel.numberOfLines = 0;
        self.myLabel.lineBreakMode = NSLineBreakByWordWrapping;
        self.myLabel.text = text;
        CGSize maxSize = CGSizeMake(self.view.bounds.size.width - 2 * self.myLabel.frame.origin.x, CGFLOAT_MAX); //I have used current window width - some margin to the both sides. you could change it to watever suitable for you
        CGSize requiredSize = [self.myLabel sizeThatFits:maxSize];
        self.myLabel.frame = CGRectMake(self.myLabel.frame.origin.x, self.myLabel.frame.origin.y, requiredSize.width, requiredSize.height);
    }
    

    And call the method from viewWillLayoutSubviews:

    -(void)viewWillLayoutSubviews {
        [super viewWillLayoutSubviews];
    
        [self adjustLabelWithText:@"Chapter One\n "
         "A Stop on the Salt Route\n "
         "1000 B.C.\n "
         "As they rounded a bend in the path that ran beside the river, Lara recognized the silhouette of a fig tree atop a nearby hill. The weather was hot and the days were long. The fig tree was in full leaf, but not yet bearing fruit."]; //whatever long text you prefer
    }
    

    This will ensure that you receive the desired effect, irrespective of the orientation change that you are possibly struggling with.