Search code examples
iosobjective-cnsstringios7deprecated

iOS7's deprecation of NSString's drawAtPoint:forWidth:withFont:minFontSize:actualFontSize:lineBreakMode:baselineAdjustment:


With iOS7's release, the following function has been deprecated:

drawAtPoint:forWidth:withFont:minFontSize:actualFontSize:lineBreakMode:baselineAdjustment:

In Apple's documentation it suggests to use

drawInRect:withAttributes:

The reason I use this function is because of the <code>minFontSize</code> parameter, which lets me draw a string inside a rect.

If the text won't fit, it will first shrink the text size to <code>minFontSize</code> and then if it doesn't fit, it will truncate it.

I am unable to accomplish this so far using <code>drawInRect:withAttributes:</code>.

Which key I can use to determine the <code>minFontSize</code> equivalent?


Solution

  • It is a little more complicated than before and you cannot use a minimum font size, but have to use minimum font scale factor. There is also a bug in the iOS SDK, which breaks it for most use cases (see notes at the bottom). Here is what you have to do:

    // Create text attributes
    NSDictionary *textAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:18.0]};
    
    // Create string drawing context
    NSStringDrawingContext *drawingContext = [[NSStringDrawingContext alloc] init];
    drawingContext.minimumScaleFactor = 0.5; // Half the font size
    
    CGRect drawRect = CGRectMake(0.0, 0.0, 200.0, 100.0);
    [string drawWithRect:drawRect
                 options:NSStringDrawingUsesLineFragmentOrigin
              attributes:textAttributes
                 context:drawingContext];
    

    Notes:

    • There seems to be a bug in the iOS 7 SDK at least up to version 7.0.3: If you specify a custom font in the attributes, the miniumScaleFactor is ignored. If you pass nil for the attributes, the text is scaled correctly.

    • The NSStringDrawingUsesLineFragmentOrigin option is important. It tells the text drawing system, that the drawing rect's origin should be at the top left corner.

    • There is no way to set the baselineAdjustment using the new method. You would have to do that yourself by calling boundingRectWithSize:options:attributes:context: first and then adjusting the rect before you pass it to drawWithRect:options:attributes:context.