I'm using the following two methods (one is a category of NSString
and the other a category of UILabel
) to automatically adjust the height of a label based on the text inside it. It's working fine for the mostpart, but it's having some unpredictable results. I'm not quite sure where the issue may be occuring and I'm hoping some of you fine folks can offer a helping hand. First off, here are the methods in question:
NSString Category:
- (CGFloat) fontSizeWithFont: (UIFont *) font constrainedToSize: (CGSize) size minimumFontSize: (CGFloat) minimumFontSize
{
CGFloat fontSize = [font pointSize];
CGFloat height = [self sizeWithFont: font constrainedToSize: CGSizeMake(size.width, FLT_MAX) lineBreakMode: NSLineBreakByWordWrapping].height;
UIFont *newFont = font;
// Reduce font size while too large, break if no height (empty string)
while (height > size.height && height != 0 && fontSize > minimumFontSize) {
fontSize--;
newFont = [UIFont fontWithName: font.fontName size: fontSize];
height = [self sizeWithFont: newFont constrainedToSize: CGSizeMake(size.width, FLT_MAX) lineBreakMode: NSLineBreakByWordWrapping].height;
};
// Loop through words in string and resize to fit
for (NSString *word in [self componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]) {
CGFloat width = [word sizeWithFont: newFont].width;
while (width > size.width && width != 0 && fontSize > minimumFontSize) {
fontSize--;
newFont = [UIFont fontWithName: font.fontName size: fontSize];
width = [word sizeWithFont: newFont].width;
}
}
return fontSize;
}
UILabel Category:
- (void) sizeToFitMultipleLines
{
if (self.adjustsFontSizeToFitWidth) {
CGFloat adjustedFontSize = [self.text fontSizeWithFont: self.font constrainedToSize: self.frame.size minimumFontSize: self.minimumScaleFactor];
self.font = [self.font fontWithSize: adjustedFontSize];
}
[self sizeToFit];
}
The issue that's occurring is that the height of the label has empty space at its top and bottom, and that the longer the string inside it is, the larger that empty space is. A single line label might have perhaps 10 pixels above and below it inside the label's frame, but a six-line string may have almost 100 pixels. I'm not able to track down where this extra space is coming from in the methods above.
Secondly, the width of the label is sometimes adjusted where I only want the height to be changed. I'm guessing that [self sizeToFit]
is what's causing this particular issue, but am not entirely sure since the height remains unadjusted if I remove it. EDIT: I've fixed this width issue by manually re-positioning the label after its been sized to fit (its X coordinate is now the screen width minus the label width, divided by 2).
Any thoughts? If you need additional info or code, please ask. I'm always setting the font before I call the [sizeToFitMultipleLines]
method on the labels in question, so that's not the issue.
I have tried this and its working for me. Hope this can help you a bit.
USE