Question

I am looking for a way of finding the correct font size in order to draw text onto a map at the correct width (which changes as the user zooms in and out of the map). I used to use the following code:

+(float) calulateHeightFromMaxWidth:(NSString*)text withMaxWidth:(float)maxWidth withMaxFontSize:(float)maxFontSize{
 CGFloat fontSize;

 [text sizeWithFont:[UIFont systemFontOfSize:maxFontSize]  minFontSize:1 actualFontSize:&fontSize forWidth:maxWidth lineBreakMode:NSLineBreakByTruncatingTail];

return fontSize;

}

This method always returned the correct answer, however sizeWithFont is depicted in iOS 7 and I cannot find a replacement that will return the font size after given it a width. I have found many posts on this site that will give you the width after you have specified a size but I cannot find the opposite (sizeWithAttributes:). I am trying to avoid a solution which involves looping through different font sizes till I find one that fits, as this method could be called 100's maybe 1000's times a draw.

Was it helpful?

Solution

Take a look at [NSString boundingRectWithSize:options:attributes:context:] You can pass MAXFLOAT for both height and width of the parameter size to get the actual size of the text.

EDIT: here's some code that calculates the ideal font size fairly efficiently, using the non-deprecated method:

+(float) calulateHeightFromMaxWidth:(NSString*)text withMaxWidth:(float)maxWidth withMaxFontSize:(float)maxFontSize{

    // The less exact you try to match the width, the fewer times the method will need to be called
    CGFloat textWidthMatchDelta = 10;
    CGFloat fontSize = maxFontSize;
    CGFloat minFontSize = 0;
    // If drawing a single line of text, omit `|NSStringDrawingUsesLineFragmentOrigin`.
    NSUInteger textOptions = NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin;

    while (YES) {
        CGRect textRect = [text boundingRectWithSize:CGSizeMake(maxWidth, MAXFLOAT)
                                             options:textOptions
                                          attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:fontSize]
                                             context:nil];
        CGFloat textWidth = CGRectGetWidth(textRect);

        if (textWidth > maxWidth) {
            maxFontSize = fontSize;
            fontSize /= 2.0f;
        } else if (textWidth + textWidthMatchDelta < maxWidth) {
            minFontSize = fontSize;
            fontSize = minFontSize + (maxFontSize - minFontSize) / 2.0f;
        } else {
            break;
        }
    }

    return fontSize;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top