Replacement for deprecated -sizeWithFont:constrainedToSize:lineBreakMode: in iOS 7?
Solution 1
You could try this:
CGRect textRect = [text boundingRectWithSize:size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:FONT}
context:nil];
CGSize size = textRect.size;
Just change "FONT" for an "[UIFont font....]"
Solution 2
As we cant use sizeWithAttributes for all iOS greater than 4.3 we have to write conditional code for 7.0 and previous iOS.
1) Solution 1:
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
CGSize size = CGSizeMake(230,9999);
CGRect textRect = [specialityObj.name
boundingRectWithSize:size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14]}
context:nil];
total_height = total_height + textRect.size.height;
}
else {
CGSize maximumLabelSize = CGSizeMake(230,9999);
expectedLabelSize = [specialityObj.name sizeWithFont:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap]; //iOS 6 and previous.
total_height = total_height + expectedLabelSize.height;
}
2) Solution 2
UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16]; // Your Font-style whatever you want to use.
gettingSizeLabel.text = @"YOUR TEXT HERE";
gettingSizeLabel.numberOfLines = 0;
CGSize maximumLabelSize = CGSizeMake(310, 9999); // this width will be as per your requirement
CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];
The first solution is sometime fail to return proper value of height. so use another solution. which will work perfectly.
The second option is quite well and working smoothly in all iOS without conditional code.
Solution 3
Here is simple solution :
Requirements :
CGSize maximumSize = CGSizeMake(widthHere, MAXFLOAT);
UIFont *font = [UIFont systemFontOfSize:sizeHere];
Now As constrainedToSizeusage:lineBreakMode:
usage is deprecated in iOS 7.0:
CGSize expectedSize = [stringHere sizeWithFont:font constrainedToSize:maximumSize lineBreakMode:NSLineBreakByWordWrapping];
Now usage in greater version of iOS 7.0 will be:
// Let's make an NSAttributedString first
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:stringHere];
//Add LineBreakMode
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
[attributedString setAttributes:@{NSParagraphStyleAttributeName:paragraphStyle} range:NSMakeRange(0, attributedString.length)];
// Add Font
[attributedString setAttributes:@{NSFontAttributeName:font} range:NSMakeRange(0, attributedString.length)];
//Now let's make the Bounding Rect
CGSize expectedSize = [attributedString boundingRectWithSize:maximumSize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;
Solution 4
Below are two simple methods that will replace these two deprecated methods.
And here are the relevant references:
If you are using NSLineBreakByWordWrapping, you don't need to specify the NSParagraphStyle, as that is the default: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index.html#//apple_ref/occ/clm/NSParagraphStyle/defaultParagraphStyle
You must get the ceil of the size, to match the deprecated methods' results. https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSString_UIKit_Additions/#//apple_ref/occ/instm/NSString/boundingRectWithSize:options:attributes:context:
+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font {
CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}];
return CGSizeMake(ceilf(size.width), ceilf(size.height));
}
+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font constrainedToSize:(CGSize)size{
CGRect textRect = [text boundingRectWithSize:size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName: font}
context:nil];
return CGSizeMake(ceilf(textRect.size.width), ceilf(textRect.size.height));
}
Solution 5
In most cases I used the method sizeWithFont:constrainedToSize:lineBreakMode: to estimate the minimum size for a UILabel to accomodate its text (especially when the label has to be placed inside a UITableViewCell)...
...If this is exactly your situation you can simpy use the method:
CGSize size = [myLabel textRectForBounds:myLabel.frame limitedToNumberOfLines:mylabel.numberOfLines].size;
Hope this might help.
user_Dennis_Mostajo
Updated on July 19, 2020Comments
-
user_Dennis_Mostajo almost 4 years
In iOS 7, the method:
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode
and the method:
- (CGSize)sizeWithFont:(UIFont *)font
are deprecated. How can I replace
CGSize size = [string sizeWithFont:font constrainedToSize:constrainSize lineBreakMode:NSLineBreakByWordWrapping];
and:
CGSize size = [string sizeWithFont:font];
-
holex over 10 yearsthe substitute method is
-sizeWithAttributes:
. -
user_Dennis_Mostajo over 10 yearsok holex thanks but, how can I use a font from label like a NSDIctionary? if my code is like: sizeWithFont:customlabel.font ;the void ask "sizeWithAttributes:<#(NSDictionary *)#>"
-
holex over 10 yearshere is the official documentation of how you can define attributes: developer.apple.com/library/ios/documentation/UIKit/Reference/…
-
-
Barlow Tucker over 10 yearsApple's documentation says that you should not call this method directly.
-
user4951 over 10 yearswhy 230, 999? Where do you get the number>
-
user4951 over 10 yearsAnd where do you mention NSLineBreakByWordWrapping? Wherre did it go?
-
Florian Friedrich over 10 years
NSLineBreakByWordWrapping
would go within aNSParagraphStyle
. So for example:NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
In the attributes you would then need to addNSParagraphStyleAttributeName: paragraphStyle.copy
... -
Florian Friedrich over 10 yearsThe 230 can be any number. It represents the width you want for your label. The 9999 I'd rather replace with INFINITY or MAXFLOAT.
-
Rivera over 10 yearsNot mentioned in iOS 7 SDK documentation at least.
-
manicaesar over 10 years@ffried in my case adding the paragraphStyle with line break other than NSLineBreakByWordWrapping caused size to be calculated for just one line… Any thoughts?
-
Florian Friedrich over 10 years@manicaesar Except for
NSLineBreakByWordWrapping
andNSLineBreakByCharWrapping
all line break modes are made for only one line (by truncating the string). I've just tested it and all line break modes work as expected. -
Florian Friedrich over 10 yearsDon't forget that
boundingRectWithSize:options:attributes:context:
returns fractional values. You need to doceil(textRect.size.height)
andceil(textRect.size.width)
respectively to get the real height/width. -
manicaesar over 10 yearsHmm, you are right, having (for example) NSLineBreakModeByTruncatingMiddle makes no sense for multiple lines. If someone want to have last line with tail truncated, he can use NSStringDrawingTruncatesLastVisibleLine. Thanks!
-
Javal Nanda about 10 yearsDoes this return exact size same as sizeWithFont ? I am facing this issue and using the above method still has a height difference of 3 to 4 pixels which causes lot of difference in UI for iOS 6.0 and iOS 7.0 when compared side by side
-
Nirav Jain about 10 yearsboundingRectWithSize is not returning correct width and height.
-
Jim about 10 yearsSecond solution is working like a charm. Thanks Nirav.
-
Dimple about 10 years"[AppHandlers zHandler]" gives an error.. "Undeclared Identifiers". How to solve that?
-
JRam13 almost 10 yearsWhat the heck is BOLIVIASize?
-
Nirav Jain almost 10 yearsboundingRectWithSize is still returning wrong output as i test it. The scenario is when you are testing for long and multiple paragraphs.
-
Sawsan almost 10 years@Nirav I faced the same problem for long paragraph, but after investigating the problem I found that I provide not accurate attributes like the font size. It was 12 and it should be 14 as in the interface builder in my case
-
Ramaraj T almost 10 yearsWelcome to StackOverFlow. Do not post a same answer again. If you need to add something to an answer, make a comment or do an edit to the answer.
-
user3575114 almost 10 yearsok..I will take that into consideration next time.Thank you for your advice.
-
Marius Soutier over 9 years
NSLineBreakByWordWrapping
is represented byNSStringDrawingUsesLineFragmentOrigin
.