在Xcode 5上将项目从iOS5.0转换为iOS7 / iOS6。下面的代码给出了编译时警告:
'sizeWithFont:constrainedToSize:lineBreakMode:'不推荐使用:首先在ios 7.0中弃用 - 使用 - boundingRectWithSize:options:attribiutes:context
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
self.lblHidden.frame = CGRectMake(58, 228, 945, 9999);
self.lblHidden.text = detailShareObj.pDesc;
CGSize size = [detailShareObj.pDesc sizeWithFont:self.lblHidden.font constrainedToSize:self.lblHidden.frame.size lineBreakMode:NSLineBreakByWordWrapping];
return 228.0+size.height+20;
}
else if (indexPath.section == 1)
{
NSString *tempPointStr = (self.shortDescArray)[indexPath.row];
self.lblHidden.frame = CGRectMake(58, 0, 945, 9999);
self.lblHidden.text = tempPointStr;
CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
return 50.0f;
}
我尝试了其他地方提出的一些建议,但如果有人能够通过提供代码中所需的更正而提供帮助,则无需任何帮助。
答案 0 :(得分:64)
我不会掩饰已弃用的功能警告。他们因为某种原因弃用了它。我相信该函数已被弃用,因为该系列NSString + UIKit函数基于UIStringDrawing库,该库不是线程安全的。如果您尝试不在主线程上运行它们(就像任何其他UIKit功能一样),您将获得不可预测的行为。特别是,如果您同时在多个线程上运行该函数,它可能会使您的应用程序崩溃。这就是为什么在iOS 6中,他们为NSAttributedStrings引入了boundingRectWithSize:...
方法。它建立在NSStringDrawing库之上,并且是线程安全的。
如果查看新的NSString boundingRectWithSize:...
函数,它会以与NSAttributeString相同的方式请求属性数组。如果我不得不猜测,iOS 7中的这个新的NSString函数只是iOS 6中NSAttributeString函数的包装器。
就此而言,如果您只支持iOS 6和iOS 7,那么我肯定会将所有NSString的sizeWithFont:...
更改为NSAttributeString的boundingRectWithSize
。如果您碰巧有一个奇怪的多线程角落案例,它会为您省去很多麻烦!这是我如何转换NSString的sizeWithFont:constrainedToSize:
:
过去是什么:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
CGSize size = [text sizeWithFont:font
constrainedToSize:(CGSize){width, CGFLOAT_MAX}];
可替换为:
NSString *text = ...;
CGFloat width = ...;
UIFont *font = ...;
NSAttributedString *attributedText =
[[NSAttributedString alloc]
initWithString:text
attributes:@
{
NSFontAttributeName: font
}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
请注意文档提及:
在iOS 7及更高版本中,此方法返回小数(大小) 返回的CGRect的组件);使用返回的大小来确定大小 视图,必须使用将其值提高到最接近的更高整数 使用ceil函数。
因此,要拉出用于调整视图大小的计算高度或宽度,我会使用:
CGFloat height = ceilf(size.height);
CGFloat width = ceilf(size.width);
答案 1 :(得分:44)
如果您希望它兼容iOS7及其下面的版本,请尝试使用此版本(使用ARC):
CGSize size;
if ([tempPointStr respondsToSelector:
@selector(boundingRectWithSize:options:attributes:context:)])
{
NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = NSTextAlignmentLeft;
NSDictionary * attributes = @{NSFontAttributeName : self.lblHidden.font,
NSParagraphStyleAttributeName : paragraphStyle};
size = [tempPointStr boundingRectWithSize:self.lblHidden.frame.size
options:NSStringDrawingUsesFontLeading
|NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil].size;
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
#pragma clang diagnostic pop
}
注意:这只是您else-if
案例的一个示例,也许您需要根据自己的需要进行一些修改。 ;)
答案 2 :(得分:10)
对于iOS7,请替换:
CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
constrainedToSize:self.lblHidden.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
使用:
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping; //set the line break mode
NSDictionary *attrDict = [NSDictionary dictionaryWithObjectsAndKeys:self.lblHidden.font, NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil];
CGSize size = [tempPointStr boundingRectWithSize:self.lblHidden.frame.size
options:NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin
attributes:attrDict context:nil].size;
答案 3 :(得分:2)
您可以使用:
UIFont *font = [UIFont boldSystemFontOfSize:16];
CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300)
options:NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName: font}
context:nil];
CGSize stringSize= new.size;
答案 4 :(得分:1)
如果您的目标是iOS 6.0+,您仍然可以使用sizeWithFont:constrainedToSize:lineBreakMode:
。只需确保项目的iOS Deployment Target
设置为6.0,编译器就不会给你这些警告。
(您可以通过单击“信息”部分中的蓝色项目选项卡(通常位于左侧,项目导航器窗格)找到此信息。)
如果您只定位iOS 7.0+,则应使用新方法boundingRectWithSize:options:attributes:context
。
答案 5 :(得分:1)
boundingRectWithSize:options:attributes:context有问题,如果字符串包含" \ n"它不会正确计算高度。 (换行符)。因此,此代码分别针对给定宽度(inWidth)计算每行的大小:
NSArray *brokenByLines=[string componentsSeparatedByString:@"\n"];
CGFloat height=0.0;
CGFloat maxWidth=0.0;
for (NSString* actString in brokenByLines) {
CGRect tSize=[actString boundingRectWithSize:CGSizeMake(inWidth, 600) options:(NSStringDrawingUsesLineFragmentOrigin | NSLineBreakByWordWrapping) attributes:@{NSFontAttributeName: inFont} context:nil];
if (maxWidth<tSize.size.width) {
maxWidth=tSize.size.width;
}
height+=tSize.size.height;
}
CGSize size= CGSizeMake(ceil(maxWidth), ceil(height));