Resizing UILabel to fit text

Posted on by in Development

UILabels are often the most convenient way to display simple text in an iPhone app however I often want a label to display variable text which may need to wrap to multiple lines. Simply increasing the height of the UILabel doesn’t help because a single line of text will be centered vertically within the label’s bounds. Instead I need to computer the size of the text I want to render and update the label’s frame’s height accordingly.

In most cases I want to adjust the size of not only a label but the view containing that label as well so I wrote a category to resize labels and their parent views.

@interface UIView (Resize)

- (CGFloat) resizeLabel:(UILabel *)theLabel;

- (CGFloat) resizeLabel:(UILabel *)theLabel shrinkViewIfLabelShrinks:(BOOL)canShrink;

@end

@implementation UIView (Resize)

- (CGFloat) resizeLabel:(UILabel *)theLabel shrinkViewIfLabelShrinks:(BOOL)canShrink {
    CGRect frame = [theLabel frame];
    CGSize size = [theLabel.text sizeWithFont:theLabel.font
    constrainedToSize:CGSizeMake(frame.size.width, 9999)
    lineBreakMode:UILineBreakModeWordWrap];
    CGFloat delta = size.height - frame.size.height;
    frame.size.height = size.height;
    [theLabel setFrame:frame];

    CGRect contentFrame = self.frame;
    contentFrame.size.height = contentFrame.size.height + delta;
    if(canShrink || delta > 0) {
        [self setFrame:contentFrame];
    }
    return delta;
}

- (CGFloat) resizeLabel:(UILabel *)theLabel {
    return [self resizeLabel:theLabel shrinkViewIfLabelShrinks:YES];
}

@end

Now my labels can always fit their text.

This sort of programmatic resizing can become a little bit tricky when it displaces other sub-views of the label’s parent view. For example a view containing three re-sizable labels would need additional logic to maintain the vertical spacing between them.

http://svn.carbonfive.com/public/jonah/ResizableLabelExample