objective-c 不推荐使用 sizeWithFont 方法。boundingRectWithSize 返回意外值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19398674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
sizeWithFont method is deprecated. boundingRectWithSize returns an unexpected value
提问by Nirav
In iOS7, sizeWithFontis deprecated, so I am using boundingRectWithSize(which returns a CGRect value). My code:
在 iOS7 中,sizeWithFont已弃用,所以我正在使用boundingRectWithSize(它返回一个 CGRect 值)。我的代码:
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?
在 中textRect,我得到的尺寸大于我maximumLabelSize的尺寸,与使用sizeWithFont. 我该如何解决这个问题?
回答by Quang Hà
How about create new label and using sizeThatFit:(CGSize)size??
如何创建新标签并使用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:
编辑:上面的代码不适用于 ios 7 及更高版本,因此请在下面使用:
CGRect textRect = [myString boundingRectWithSize:maximumLabelSize
options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName:fontText}
context:nil];
回答by Maxim Pavlov
Maybe you need to provide additional option to the method that is suggested in thisanswer:
也许您需要为此答案中建议的方法提供其他选项:
CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);
CGRect textRect = [myString boundingRectWithSize:maximumLabelSize
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName: fontText}
context:nil];
回答by Rikco
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.
我在计算高度上加了4px,因为没有这4px,就少了一行。
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.
我在 tableView 中使用此代码片段并将“高度”添加到 NSNumbers 数组中,然后我获得了默认 textLabel 的正确单元格高度。
Add 4 more pixel if you want more space under the text in the textLabel.
如果您希望 textLabel 中的文本下方有更多空间,请再添加 4 个像素。
**** 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.
我不同意“40px 的宽度错误”,我大喊是缺少高度的 4px,因为 4px 是字母和单行边界之间空格的默认高度。您可以使用 UILabel 进行检查,对于 16 的字体大小,您需要 UILabel 高度为 20。
But if your last line has no "g" or whatever in it, the measuring could be miss the 4px of height.
但是,如果您的最后一行没有“g”或其他任何内容,则测量值可能会错过 4px 的高度。
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.
我用一个小方法重新检查了它,我的标签准确高度为 20,40 或 60,正确宽度小于 300px。
To support iOS6 and iOS7, you can use my method:
支持iOS6和iOS7,可以使用我的方法:
- (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.
感谢您的评论,我升级了我的功能如下。由于不推荐使用 sizeWithFont 并且您将在 XCode 中收到警告,因此我添加了诊断编译指示代码以删除此特定函数调用/代码块的警告。
- (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.
除了 4px 主题:根据您使用的字体和字体粗细,计算返回不同的高度值。就我而言:字体大小为 16.0 的 HelveticaNeue-Medium 为单行返回 20.0 的行高,但为两行返回 39.0,对于 4 行返回 78px --> 每行缺少 1px - 从第 2 行开始 - 但你想要为每一行设置你的 fontsize + 4px linespace 你必须得到一个高度结果。
请在编码时记住这一点!
我还没有针对这个“问题”的函数,但我会在完成后更新这篇文章。
回答by Myrddin
The @SoftDesigner's comment has worked for me
@SoftDesigner 的评论对我有用
CGRect descriptionRect = [description boundingRectWithSize:CGSizeMake(width, 0)
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}
context:nil];
result = ceil(descriptionRect.size.height);
回答by vinaut
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)?
如果我理解正确,您正在使用 boundingRectWithSize: 就像获取 sizeWithFont 大小的一种方式(意味着您直接想要 CGSize,而不是 CGRect)?
This looks like what you are looking for :
这看起来像你在找什么:
Replacement for deprecated sizeWithFont: in iOS 7?
替换已弃用的 sizeWithFont: 在 iOS 7 中?
They are using sizeWithAttributes: to get the size, as a replacement for sizeWithFont.
他们使用 sizeWithAttributes: 来获取大小,作为 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}];
回答by Pratik
for finding size of label run time sizewithfontis deprecated for iOS 7.0 instead of that you have to use -boundingRectWithSize:options:attributes:context:method
对于iOS 7.0,不推荐使用sizewithfont来查找标签运行时的大小,而不是您必须使用-boundingRectWithSize:options:attributes:context:方法
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.
试试这个它对我有用。

