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