不推荐使用sizeWithFont方法.boundingRectWithSize返回意外值

Nir*_*rav 80 objective-c nsstring uilabel ios7

在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);
Run Code Online (Sandbox Code Playgroud)

textRect,我的尺寸大于我maximumLabelSize,尺寸与使用时不同sizeWithFont.我该如何解决这个问题?

Qua*_* Hà 150

如何创建新标签和使用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];
Run Code Online (Sandbox Code Playgroud)

编辑:这个高级代码不适合ios 7及以上版本,请使用以下内容:

CGRect textRect = [myString boundingRectWithSize:maximumLabelSize   
                         options:NSStringDrawingUsesLineFragmentOrigin| NSStringDrawingUsesFontLeading
                         attributes:@{NSFontAttributeName:fontText}
                         context:nil];
Run Code Online (Sandbox Code Playgroud)

  • 创建标签来计算字体大小?那太浪费了! (26认同)
  • @Ossir,你有更好的主意吗? (13认同)

Max*_*lov 35

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

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

  • 伙计们,不要忘记Apple声明:__在iOS 7及更高版本中,此方法返回小数大小(在返回的CGRect的大小组件中); 要使用返回的大小来调整视图大小,必须使用ceil函数将其值提升到最接近的更高整数.__ (12认同)
  • 看起来`boundingRectWithSize`被打破了.我在iOS 7,7.1.1上测试过它返回的结果不正确. (3认同)
  • ceil对我来说还不够,但发现使用ceil并添加0.5就可以了 (2认同)

Rik*_*kco 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)
Run Code Online (Sandbox Code Playgroud)

我将4px添加到计算的高度,因为如果没有这些4px,则会丢失一行.

我在tableView中使用此代码片段并将"height"添加到NSNumbers数组中,并获得默认textLabel的正确单元格高度.

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

****更新****

我不同意"40px的宽度错误",我说是4px的缺失高度,因为4px是字母和单行界限之间的空格的默认高度.您可以使用UILabel进行检查,对于16的字体大小,您需要UILabel高度为20.

但是如果你的最后一行没有"g"或其他任何东西,测量可能会错过4px的高度.

我用一点方法重新检查它,我的标签高度为20,40或60,右边宽度小于300px.

要支持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;
}
Run Code Online (Sandbox Code Playgroud)

****UPGRADE****

感谢您的评论,我按照以下方式升级了我的功能.由于不推荐使用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);
}
Run Code Online (Sandbox Code Playgroud)

除了4px主题:根据您使用的字体和字体权重,计算返回不同的高度值.在我的情况下:HelveticaNeue-Medium的字体大小为16.0,单行返回20.0的行高,但两行为39.0,4行为78px - 每行丢失> 1px - 从第2行开始 - 但你想要要获得高度结果的每一行都有你的fontsize + 4px行间距.
编码时请记住这一点!
我还没有针对这个"问题"的功能,但我会在完成后更新这篇文章.