不推荐使用 sizeWithFont 方法。 bound ingRectWithSize 返回意外值

在 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);

textRect中,我得到了一个比我的 maximumLabelSize大的尺寸,一个与使用 sizeWithFont时不同的尺寸。我该如何解决这个问题?

66954 次浏览

如果我理解正确的话,您正在使用 bound ingRectWithSize: 就像使用 sizeWithFont 获得大小一样(这意味着您想直接使用 CGSize,而不是 CGRect) ?

这看起来就是你要找的东西:

取代废弃的 sizeWithFont: 在 iOS7中?

他们使用 sizeWithAttritribute: 来获取大小,作为 sizeWithFont 的替代品。

你还会用这样的东西得到错误的尺寸吗:

UIFont *fontText = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16];
// you can use your font.


expectedLabelSize = [myString sizeWithAttributes:@{NSFontAttributeName:fontText}];

也许你需要提供额外的选项的方法是建议在 这个的答案:

CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);
CGRect textRect = [myString boundingRectWithSize:maximumLabelSize
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName: fontText}
context:nil];

如何创建新的标签和使用 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];

编辑: 这上面的代码对 ios 7及以上版本不适用,所以请使用以下代码:

CGRect textRect = [myString boundingRectWithSize:maximumLabelSize
options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName:fontText}
context:nil];

为了查找标签运行时的大小,iOS 7.0不推荐使用 字体大小,而必须使用 选项: 属性: 上下文:方法

你可以像下面的代码一样使用它

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;

在这里你必须给宽度的最大长度找到高度或宽度。

试试这个,对我有用。

下面是我的工作代码片段:

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)

我在计算的高度上增加了4px,因为如果没有这些4px,就会少一行。

我在 tableView 中使用这个代码片段,并将“ height”添加到一个 NSNumbers 数组中,然后得到默认 textLabel 的正确单元格高度。

如果您希望在 textLabel 中的文本下面有更多的空间,请再添加4个像素。

最新消息

我不同意“40px 的宽度错误”,我呼吁是缺少高度的4px,因为4px 是一个字母和一行边界之间空格的默认高度。 您可以使用 UILabel 检查它,对于字体大小为16的字体,您需要使用高度为20的 UILabel。

但是如果你的最后一行没有“ g”或者其他什么,测量结果可能会错过4px 的高度。

我用一个小方法重新检查了一下,我得到了一个精确的高度20,40或60 对于我的标签和右边宽度小于300像素。

为了支持 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;
}

升级一下

感谢您的评论,我如下更新了我的功能。由于 sizeWithFont 是不推荐的,并且您将在 XCode 中获得一个警告,因此我添加了 Diagnos- 杂注-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);
}

除了4像素的话题: 根据您使用的字体和字体重量,计算将返回不同的高度值。在我的例子中: HelveticaNeue-Medium 的字体大小为16.0,返回一行的行高为20.0,两行的行高为39.0,4行的行高为78px ——每行缺少1 px-从第2行开始-但是你想让你的字体大小 + 4px 行空间为每一行你必须得到一个高度-结果。
编写代码时请记住这一点!
我还没有一个函数为这个“问题”,但我会更新这篇文章时,我完成了。

@ SoftDesigner 的评论对我很有用

CGRect descriptionRect = [description boundingRectWithSize:CGSizeMake(width, 0)
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}
context:nil];
result = ceil(descriptionRect.size.height);