iOS7's deprecation of NSString's drawAtPoint:forWidth:withFont:minFontSize:actualFontSize:lineBreakMode:baselineAdjustment:
Solution 1
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 todrawWithRect:options:attributes:context
.
Solution 2
After googling for a long time I did not find a solution working under iOS7.
Right now I use the following workaround, knowing that it is very ugly.
I render a UILabel in memory, take a screenshot and draw that.
UILabel is able to shrink the text correctly.
Perhaps someone finds it useful.
UILabel *myLabel = [[UILabel alloc] initWithFrame:myLabelFrame];
myLabel.font = [UIFont fontWithName:@"HelveticaNeue-BoldItalic" size:16];
myLabel.text = @"Some text that is too long";
myLabel.minimumScaleFactor = 0.5;
myLabel.adjustsFontSizeToFitWidth = YES;
myLabel.backgroundColor = [UIColor clearColor];
UIGraphicsBeginImageContextWithOptions(myLabelFrame.size, NO, 0.0f);
[[myLabel layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[screenshot drawInRect:myLabel.frame];
Related videos on Youtube
Rob
Updated on September 26, 2022Comments
-
Rob over 1 year
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? -
Rob over 10 yearsadding minFontSize as a key doesn't really change anything.
-
heczaco over 10 yearsyep, sorry, i didn't read your question correctly, I couldn't find any key in the documentation that does exactly what minFontSize would do, but maybe playing with this key would work, "NSStrokeWidthAttributeName" , hope it helps
-
Rob over 10 yearsAccording to the documentation, your answer is correct. However, as you indicate, there seems to be a bug and this is getting ignored. I didn't try your suggestion of leaving attributes nil, since I do require to pass in some attributes, or the returned size will be incorrect anyway. I'm marking this answer as correct. Thank you!
-
Aaron almost 7 yearsAdd some additional context to this answer to help people understand why this is a good answer, rather than just posting raw code.