sizeWithFont:constrainedToSize:lineBreakMode: 在 iOS7 中已弃用
Posted
技术标签:
【中文标题】sizeWithFont:constrainedToSize:lineBreakMode: 在 iOS7 中已弃用【英文标题】:sizeWithFont:constrainedToSize:lineBreakMode: deprecated in iOS7 【发布时间】:2013-09-16 17:52:56 【问题描述】:我正在将我的应用程序更新到 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:
我不知道如何将我的早期版本转换为这种新方法,如果有人可以帮助我,那就太好了。提前致谢。
【问题讨论】:
【参考方案1】: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];
【讨论】:
【参考方案2】:如果您只支持 ios6 及更高版本,您可以将您的NSStrings
转换为NSAttributedStrings
并使用NSAttributedString
的boundingRectWithSize: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 中,NSAttributedStrings
的新 NSStringDrawing 函数被公开,boundingRectWithSize:...
函数是线程安全的。我猜这就是为什么在 ios7 中,旧的 sizeWithFont:...
函数已被弃用。
请注意文档中提到的:
在 iOS 7 及更高版本中,此方法返回小数大小(在大小 返回的 CGRect 的组成部分);使用返回的大小来调整大小 视图,您必须使用将其值提高到最接近的更高整数 使用 ceil 函数。
所以要提取用于调整视图大小的计算高度或宽度,我会使用:
CGFloat height = ceilf(size.height);
CGFloat width = ceilf(size.width);
【讨论】:
【参考方案3】:您使用的 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];
【讨论】:
以上是关于sizeWithFont:constrainedToSize:lineBreakMode: 在 iOS7 中已弃用的主要内容,如果未能解决你的问题,请参考以下文章