In iOS7, sizeWithFont
is deprecated, so I am using boundingRectWithSize
(which returns a CGRect value). My code:
UIFont *fontText = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16];
// you can use your font.
CGSize maximumLabelSize = CGSizeMake(310, 9999);
CGRect textRect = [myString boundingRectWithSize:maximumLabelSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:fontText}
context:nil];
expectedLabelSize = CGSizeMake(textRect.size.width, textRect.size.height);
In textRect
, I'm getting a size greater than my maximumLabelSize
, a different size than when using sizeWithFont
. How can I resolve this issue?
How about create new label and using sizeThatFit:(CGSize)size
??
UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:@"YOUR FONT's NAME" size:16];
gettingSizeLabel.text = @"YOUR LABEL's TEXT";
gettingSizeLabel.numberOfLines = 0;
gettingSizeLabel.lineBreakMode = NSLineBreakByWordWrapping;
CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);
CGSize expectSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];
Edit: This upper code is not good for ios 7 and above, so please use below:
CGRect textRect = [myString boundingRectWithSize:maximumLabelSize
options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName:fontText}
context:nil];
Maybe you need to provide additional option to the method that is suggested in this answer:
CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);
CGRect textRect = [myString boundingRectWithSize:maximumLabelSize
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName: fontText}
context:nil];
Here is my working code snippet:
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:attributeDict];
NSString *headline = [dict objectForKey:@"title"];
UIFont *font = [UIFont boldSystemFontOfSize:18];
CGRect rect = [headline boundingRectWithSize:CGSizeMake(300, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
CGFloat height = roundf(rect.size.height +4)
I added 4px to the calculated height, because without these 4px, there is one line missing.
I use this code snippet in a tableView and add the "height" to an array of NSNumbers and I get the correct cell height for the default textLabel.
Add 4 more pixel if you want more space under the text in the textLabel.
**** UPDATE ****
I do not agree with the "width bug of 40px", I shout be the 4px of missing height, because 4px is the default height of a space between a letter and the bound of a single line.
You can check it with a UILabel, for a fontsize of 16 you need a UILabel height of 20.
But if your last line has no "g" or whatever in it, the measuring could be miss the 4px of height.
I rechecked it with a little method, I get an accurate height of 20,40 or 60
for my label and a right width less than 300px.
To support iOS6 and iOS7, you can use my method:
- (CGFloat)heightFromString:(NSString*)text withFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
CGRect rect;
float iosVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (iosVersion >= 7.0) {
rect = [text boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
}
else {
CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
rect = CGRectMake(0, 0, size.width, size.height);
}
NSLog(@"%@: W: %.f, H: %.f", self, rect.size.width, rect.size.height);
return rect.size.height;
}
**** UPGRADE ****
Thanks to your comments, I upgraded my function as followed. Since sizeWithFont is deprecated and you will get a warning in XCode, I added the diagnostic-pragma-code to remove the warning for this particular function-call/block of code.
- (CGFloat)heightFromStringWithFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
CGRect rect;
if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
rect = [self boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
}
else {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
CGSize size = [self sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
rect = CGRectMake(0, 0, size.width, size.height);
#pragma GCC diagnostic pop
}
return ceil(rect.size.height);
}
In addition to the 4px topic:
depending which font and font-weight you use, the calculation returns different height-values. In my case: HelveticaNeue-Medium with a fontsize of 16.0 returns a line-height of 20.0 for a single line but 39.0 for two lines, 78px for 4 lines --> 1px missing for every line - beginning with line 2 - but you want to have your fontsize + 4px linespace for every line you have to get a height-result.
Please keep that in mind while coding!
I don´t have a function yet for this "problem" but I will update this post when I´m finished.
If I understand correctly, you are using boundingRectWithSize: just as a way of getting the size you would get with sizeWithFont (meaning you want directly the CGSize, not the CGRect)?
This looks like what you are looking for :
Replacement for deprecated sizeWithFont: in iOS 7?
They are using sizeWithAttributes: to get the size, as a replacement for sizeWithFont.
Do you still get the wrong size using something like this :
UIFont *fontText = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16];
// you can use your font.
expectedLabelSize = [myString sizeWithAttributes:@{NSFontAttributeName:fontText}];
The @SoftDesigner's comment has worked for me
CGRect descriptionRect = [description boundingRectWithSize:CGSizeMake(width, 0)
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}
context:nil];
result = ceil(descriptionRect.size.height);
for finding size of label run time sizewithfont is deprecated for iOS 7.0 instead of that you have to use -boundingRectWithSize:options:attributes:context: method
you can use it like below code
CGSize constraint = CGSizeMake(MAXIMUM_WIDHT, TEMP_HEIGHT);
NSRange range = NSMakeRange(0, [[self.message body] length]);
NSDictionary *attributes = [YOUR_LABEL.attributedText attributesAtIndex:0 effectiveRange:&range];
CGSize boundingBox = [myString boundingRectWithSize:constraint options:NSStringDrawingUsesFontLeading attributes:attributes context:nil].size;
int numberOfLine = ceil((boundingBox.width) / YOUR_LABEL.frame.size.width);
CGSize descSize = CGSizeMake(ceil(boundingBox.width), ceil(self.lblMessageDetail.frame.size.height*numberOfLine));
CGRect frame=YOUR_LABEL.frame;
frame.size.height=descSize.height;
YOUR_LABEL.frame=frame;
here you have to give width to maximum length for finding height or width.
try this it is working for me.