Snugly fitting UILabels

November 24th, 2010
#ui

On a project I had to come up with a way of dynamically adjusting a label's frame to match the content that was inside it. I first thought of using a UITextView instead of a label as my data could very well be multi-lined but decided against it when I discovered this approach:

.h

@interface UILabel(Size)

-(void)setUpMultiLineFrameBasedOnWidth:(CGFloat)width withStartXPosition:(CGFloat)startX withHeight:(CGFloat)maxHeight;

-(CGFloat)getHeightBasedOnWidth:(CGFloat)maxWidth;

@end

.m

@implementation UILabel(Size)

-(void)setUpMultiLineFrameBasedOnWidth:(CGFloat)maxWidth withStartXPosition:(CGFloat)startX withHeight:(CGFloat)maxHeight{
	self.lineBreakMode = UILineBreakModeWordWrap;
	self.numberOfLines = 0; //instructs the label that contain any number of lines

	CGFloat labelHeight = [self getHeightBasedOnWidth:maxWidth];
	CGFloat padding = ((maxHeight - labelHeight)/2); //center label within maxHeight box
	[self setFrame:CGRectMake(startX, padding, maxWidth, labelHeight)];
}

-(CGFloat)getHeightBasedOnWidth:(CGFloat)maxWidth{

	CGSize size = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(maxWidth, 9999) lineBreakMode:self.lineBreakMode]; //the 9999 here is used to indicate that it can a very long label if need be

	return size.height;
}

@end

In order to use this method you need to have set-up your label with a font before calling the category methods.

What do you think? Let me know by getting in touch on Twitter - @wibosco