[objective-c] Replacement for deprecated sizeWithFont: in iOS 7?

I believe the function was deprecated because that series of NSString+UIKit functions (sizewithFont:..., etc) were based on the UIStringDrawing library, which wasn't thread safe. If you tried to run them not on the main thread (like any other UIKit functionality), you'll get unpredictable behaviors. In particular, if you ran the function on multiple threads simultaneously, it'll probably crash your app. This is why in iOS 6, they introduced a the boundingRectWithSize:... method for NSAttributedString. This was built on top of the NSStringDrawing libraries and is thread safe.

If you look at the new NSString boundingRectWithSize:... function, it asks for an attributes array in the same manner as a NSAttributeString. If I had to guess, this new NSString function in iOS 7 is merely a wrapper for the NSAttributeString function from iOS 6.

On that note, if you were only supporting iOS 6 and iOS 7, then I would definitely change all of your NSString sizeWithFont:... to the NSAttributeString boundingRectWithSize. It'll save you a lot of headache if you happen to have a weird multi-threading corner case! Here's how I converted NSString sizeWithFont:constrainedToSize::

What used to be:

NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font 
               constrainedToSize:(CGSize){width, CGFLOAT_MAX}];

Can be replaced with:

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;

Please note the documentation mentions:

In iOS 7 and later, this method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must use raise its value to the nearest higher integer using the ceil function.

So to pull out the calculated height or width to be used for sizing views, I would use:

CGFloat height = ceilf(size.height);
CGFloat width  = ceilf(size.width);

Examples related to objective-c

Adding a UISegmentedControl to UITableView Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Warp \ bend effect on a UIView? Use NSInteger as array index Detect if the device is iPhone X Linker Command failed with exit code 1 (use -v to see invocation), Xcode 8, Swift 3 ITSAppUsesNonExemptEncryption export compliance while internal testing? How to enable back/left swipe gesture in UINavigationController after setting leftBarButtonItem? Change status bar text color to light in iOS 9 with Objective-C

Examples related to deprecated

Html.fromHtml deprecated in Android N Is `shouldOverrideUrlLoading` really deprecated? What can I use instead? getResources().getColor() is deprecated ActionBarActivity is deprecated Deprecated: mysql_connect() Replacement for deprecated sizeWithFont: in iOS 7? jQuery 1.9 .live() is not a function The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead How to declare or mark a Java method as deprecated? Is the buildSessionFactory() Configuration method deprecated in Hibernate

Examples related to ios7

Xcode: Could not locate device support files How to Apply Gradient to background view of iOS Swift App How do I hide the status bar in a Swift iOS app? Using Predicate in Swift How do I programmatically set device orientation in iOS 7? What is the height of Navigation Bar in iOS 7? Warning :-Presenting view controllers on detached view controllers is discouraged Color Tint UIButton Image iOS change navigation bar title font and color How to embed small icon in UILabel