83

在 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。我该如何解决这个问题?

4

6 回答 6

152

如何创建新标签并使用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];
于 2013-10-22T12:54:15.557 回答
37

也许您需要为此答案中建议的方法提供其他选项:

CGSize maximumLabelSize = CGSizeMake(310, CGFLOAT_MAX);
CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                                         options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                      attributes:@{NSFontAttributeName: fontText}
                                         context:nil];
于 2013-10-21T09:15:52.867 回答
15

这是我的工作代码片段:

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 中使用此代码片段并将“高度”添加到 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 中收到警告,因此我添加了 diagnostic-pragma-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);
}

除了 4px 主题:根据您使用的字体和字体粗细,计算返回不同的高度值。在我的情况下:字体大小为 16.0 的 HelveticaNeue-Medium 返回单行的行高 20.0,但两行返回 39.0,4 行返回 78px -> 每行缺少 1px - 从第 2 行开始 - 但你想要为每一行设置你的字体大小 + 4px 行空间,你必须得到一个高度结果。
编码时请记住这一点!
我还没有解决这个“问题”的功能,但我会在完成后更新这篇文章。

于 2014-07-07T16:12:29.373 回答
2

如果我理解正确,您使用的是 boundingRectWithSize: 就像获取 sizeWithFont 获得的大小的一种方式(意味着您直接想要 CGSize,而不是 CGRect)?

这看起来像您正在寻找的内容:

替换已弃用的 sizeWithFont:在 iOS 7 中?

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

你仍然使用这样的东西得到错误的尺寸:

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

expectedLabelSize = [myString sizeWithAttributes:@{NSFontAttributeName:fontText}];
于 2013-10-19T08:15:53.020 回答
2

@SoftDesigner 的评论对我有用

CGRect descriptionRect = [description boundingRectWithSize:CGSizeMake(width, 0)
                                                       options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                                    attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:12]}
                                                       context:nil];
result = ceil(descriptionRect.size.height);
于 2016-04-21T15:00:44.857 回答
1

对于 iOS 7.0,不推荐使用sizewithfont来查找标签运行时的大小,而不是您必须使用-boundingRectWithSize:options:attributes:context:方法

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

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;

在这里,您必须将宽度指定为最大长度才能找到高度或宽度。

试试这个它对我有用。

于 2013-10-25T08:46:39.620 回答