在iOS7中,sizeWithFont:constrainedToSize:lineBreakMode:已经被弃用。

6

我正在将我的应用更新到iOS 7,终于搞定了,但有一件事情我找不到解决方法。

在Xcode 4中,我使用了以下方法:

#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 280.0f
#define CELL_CONTENT_MARGIN 10.0f


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; {
    NSString *text = [textA objectAtIndex:[indexPath row]];

    CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];

    CGFloat height = MAX(size.height, 28.0f);

    return height + (CELL_CONTENT_MARGIN * 2);
}

但是在iOS 7中使用它时,会出现错误:

请使用-boundingRectWithSize:options:attributes:context:

我不知道如何将我的早期版本转换为这种新方法,如果有人能帮忙,那就太好了。提前感谢。

3个回答

5

sizeWithFont方法在iOS7中已被弃用。您应该使用boundingRectWithSize代替。如果您还需要支持早期的iOS版本,则可以使用以下代码:

CGSize size = CGSizeZero;

if ([label.text respondsToSelector: @selector(boundingRectWithSize:options:attributes:context:)] == YES) {
    size = [label.text boundingRectWithSize: constrainedSize options: NSStringDrawingUsesLineFragmentOrigin
                                 attributes: @{ NSFontAttributeName: label.font } context: nil].size;
} else {
    size = [label.text sizeWithFont: label.font constrainedToSize: constrainedSize lineBreakMode: UILineBreakModeWordWrap];
}

4
如果您只支持iOS6及更高版本,则可以将NSStrings转换为NSAttributedStrings,并使用NSAttributedStringboundingRectWithSize:options:context:
以前的代码如下:
CGSize size = [text sizeWithFont:font
               constrainedToSize:(CGSize){maxWidth, CGFLOAT_MAX}];

可以轻松将其转换为以下代码,适用于ios6和ios7:

NSAttributedString *attributedText =
    [[NSAttributedString alloc]
        initWithString:text
        attributes:@
        {
            NSFontAttributeName:    font
        }];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){maxWidth, CGFLOAT_MAX}
                                           options:NSStringDrawingUsesLineFragmentOrigin
                                           context:nil];
CGSize size = rect.size;

作为一个旁注,这种做法的好处在于,您在ios6中的文本大小现在是线程安全的。旧的sizeWithFont:...方法属于UIStringDrawing,如果您同时在两个线程上运行sizeWithFont:...,则会崩溃。在ios6中,新的NSStringDrawing函数用于NSAttributedStrings,并且boundingRectWithSize:...函数是线程安全的。我猜这就是为什么在ios7中,旧的sizeWithFont:...函数被弃用的原因。
请注意文档中提到:
在iOS 7及更高版本中,此方法返回小数大小(在返回CGRect的大小组件中);要使用返回的大小调整视图大小,必须使用ceil函数将其值提高到最近的较高整数。
因此,要获取用于调整视图大小的计算高度或宽度,我将使用:
CGFloat height = ceilf(size.height);
CGFloat width  = ceilf(size.width);

2

您正在使用的sizeWithFont API在iOS7上已经过时。

// See UIStringDrawing.h
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(NSLineBreakMode)lineBreakMode NS_DEPRECATED_IOS(2_0, 7_0, "Use -boundingRectWithSize:options:attributes:context:"); // NSTextAlignment is not needed to determine size

您可以这样使用API建议:
NSMutableDictionary *atts = [[NSMutableDictionary alloc] init];
[atts setObject:myFont forKey:NSFontAttributeName];

CGRect rect = [myText boundingRectWithSize:constraint
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:atts
                                 context:nil];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接