Keywords: iOS 7 | sizeWithFont deprecated | thread safety
Abstract: This article explores the replacement for the deprecated sizeWithFont: method in iOS 7, focusing on the use of sizeWithAttributes: and boundingRectWithSize: methods. Through code examples and in-depth analysis, it explains how to correctly pass UIFont objects, handle fractional sizes, and ensure thread safety. The discussion includes strategies for transitioning from NSString to NSAttributedString, providing a comprehensive migration guide for developers.
Introduction
In iOS 7, the sizeWithFont: method was deprecated, necessitating a shift to more modern APIs. This article aims to dissect this change and offer practical alternatives.
Core Replacement Method: sizeWithAttributes:
The sizeWithAttributes: method accepts an NSDictionary parameter containing text attributes. To pass a font object, use the key NSFontAttributeName. Here is a basic example:
CGRect rawRect = {};
rawRect.size = [string sizeWithAttributes: @{
NSFontAttributeName: [UIFont systemFontOfSize:17.0f],
}];
CGSize adjustedSize = CGRectIntegral(rawRect).size;Note that the returned size may be fractional; it is recommended to use CGRectIntegral or the ceil function to adjust for accurate view sizing.
Thread Safety and Advanced Solution: boundingRectWithSize:
One reason for deprecating sizeWithFont: is its reliance on the UIStringDrawing library, which is not thread-safe. The boundingRectWithSize: method for NSAttributedString, introduced in iOS 6, offers a thread-safe alternative. Here is an example of converting old code:
Old code:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font
constrainedToSize:(CGSize){width, CGFLOAT_MAX}];New code:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
NSAttributedString *attributedText =
[[NSAttributedString alloc] initWithString:text
attributes:@{NSFontAttributeName: font}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
CGFloat height = ceilf(size.height);
CGFloat width = ceilf(size.width);This approach not only addresses the deprecation but also enhances application stability in multi-threaded environments.
Conclusion
Migrating to sizeWithAttributes: or boundingRectWithSize: is key to handling the deprecation of sizeWithFont: in iOS 7. Developers should choose the appropriate method based on application needs and handle fractional sizes to ensure compatibility.