Similar to resizing a UIView when the orientation changes, it can be useful to have a UILabel automatically resize itself based on its text.

For example, let’s say you have a UILabel with a UITextView below it, and you want the UITextView to stay anchored below the UILabel.

Here’s how you’d do it:

– (void)refreshTextLayout
{
    CGRect myLabelFrame = [self.myLabel frame];
    CGSize myLabelSize = [self.myLabel.text         sizeWithFont:self.myLabel.font
        constrainedToSize:CGSizeMake(myLabelFrame.size.width, 9999)
        lineBreakMode:UILineBreakModeWordWrap];

    CGFloat delta = myLabelSize.height – myLabelFrame.size.height;

    myLabelFrame.size.height = myLabelSize.height;
    [self.myLabel setFrame:myLabelFrame];

    CGRect myTextViewFrame = [self.myTextView frame];
    myTextViewFrame.origin.y += delta;
    myTextViewFrame.size.height -= delta;
    [self.myTextView setFrame:myTextViewFrame];
}


This code measures the size of the text in the UILabel (given its current width) and adjusts the UILabel’s frame to fit the text. It then updates the UITextView’s frame to reposition it below the UILabel and adjusts its height to fill the remainder of the view.

So how does this happen automagically?

You simply need to invoke refreshTextLayout in the viewWillAppear and didRotateFromInterfaceOrientation methods in the parent view controller:

– (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self refreshTextLayout];
}

– (void)didRotateFromInterfaceOrientation:
        (UIInterfaceOrientation)fromInterfaceOrientation
{
    [self refreshTextLayout];
}

– (BOOL)shouldAutorotateToInterfaceOrientation:
        (UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}


If you don’t need to support multiple device orientations then you can omit the last two methods above.