I'm having a bit of trouble working out the "best" way to render text in my application.
My main view consists of a text view, and the design of the application dictates a few things:
At the moment i'm using a UILabel and the following code to try and guess the best font size to use for the amount of text:
txt = @"this is just some sample text";
mylabel.font = [self getFontForString:txt];
mylabel.adjustsFontSizeToFitWidth = YES;
mylabel.numberOfLines = 0;
[mylabel setText:txt];
And:
- (UIFont *) getFontForString:(NSString *)txt {
CGFloat textLength = txt.length;
CGFloat maxFontSize = 71;
CGFloat minFontSize = 27;
CGFloat newFontSize = 0;
NSArray *chunks = [txt componentsSeparatedByString:@" "];
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"length" ascending:NO] autorelease];
NSArray *sortedChunks = [chunks sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
CGSize labelSize = theThingLabel.bounds.size;
CGSize projectedSize = [[sortedChunks objectAtIndex:0] sizeWithFont:[UIFont boldSystemFontOfSize:maxFontSize]];
if (projectedSize.width > labelSize.width) {
CGFloat percentageDifference = ((projectedSize.width - labelSize.width)/labelSize.width)*100;
if (percentageDifference > 50) {
newFontSize = ((minFontSize/percentageDifference)*100) - 10;
if (newFontSize < minFontSize) newFontSize = minFontSize;
} else {
newFontSize = ((percentageDifference/maxFontSize)*100) - 10;
if(newFontSize < (maxFontSize/2)) newFontSize = maxFontSize - abs(newFontSize);
}
} else {
if ( textLength > 11 && textLength < 255) {
newFontSize = (maxFontSize - ((maxFontSize - minFontSize) * ((textLength- 11) / 100)));
} else if (textLength <= 11) {
newFontSize = maxFontSize;
} else if (textLength >= 255) {
newFontSize = minFontSize;
}
}
return [UIFont boldSystemFontOfSize:newFontSize];
}
This works, to an extent, but often falls over when the text is a bit on the long side, these two example show it rendering the following strings:
As you can see in the second example (with far longer text) there are a number of issues:
So with all this in mind, what are my options, I'm open to moving to using coretext if this is the right solution, but have no idea where to start, it's also possible I've made a mistake which I just can't see in my "font size guessing" code.
Make text bigger on your screenTo go to the Ease of Access settings on your computer, press the Windows key+U. Under Make text bigger on the Display tab, drag the slider to the right to increase the size of the sample text. Once you're happy with the text size, select Apply. Windows scales up the size of all text.
The following method will be use full to get the font size for specific string for specific rectangle (area).
-(float) maxFontSizeThatFitsForString:(NSString*)_string inRect:(CGRect)rect withFont:(NSString *)fontName onDevice:(int)device {
// this is the maximum size font that will fit on the device
float _fontSize = maxFontSize;
float widthTweak;
// how much to change the font each iteration. smaller
// numbers will come closer to an exact match at the
// expense of increasing the number of iterations.
float fontDelta = 2.0;
// sometimes sizeWithFont will break up a word
// if the tweak is not applied. also note that
// this should probably take into account the
// font being used -- some fonts work better
// than others using sizeWithFont.
if(device == IPAD)
widthTweak = 0.2;
else
widthTweak = 0.2;
CGSize tallerSize = CGSizeMake(rect.size.width-(rect.size.width*widthTweak), 100000);
CGSize stringSize = CGSizeZero;
if([[UIDevice currentDevice].systemVersion floatValue]>=7.0){
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:[UIFont boldSystemFontOfSize:17] forKey: NSFontAttributeName];
stringSize = [_string boundingRectWithSize: tallerSize options:NSStringDrawingUsesLineFragmentOrigin attributes:stringAttributes context:nil].size;
}
else{
stringSize = [_string sizeWithFont:[UIFont fontWithName:fontName size:_fontSize] constrainedToSize:tallerSize];
}
while (stringSize.height >= rect.size.height)
{
_fontSize -= fontDelta;
stringSize = [_string sizeWithFont:[UIFont fontWithName:fontName size:_fontSize] constrainedToSize:tallerSize];
}
return _fontSize;
}
Use this and get the font size and assign to the label.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With