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