'sizeWithFont:constrainedToSize:lineBreakMode:'已弃用:

在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; } 

我试了一些build议给其他地方,但没有什么是救援,如果有人可以帮助通过给代码中所要求的更正将不胜感激。

我不会掩盖弃用的函数警告。 他们不赞成这个理由。 我相信该函数已被弃用,因为这一系列的NSString + UIKit函数是基于UIStringDrawing库,这是不是线程安全的。 如果您尝试在主线程上运行它们(与任何其他UIKitfunction一样),则会出现不可预知的行为。 特别是,如果您同时在多个线程上运行该function,可能会导致应用程序崩溃。 这就是为什么在iOS 6中,他们引入了NSAttributedStrings的boundingRectWithSize:...方法。 这是build立在NSStringDrawing库的顶部,是线程安全的。

如果您查看新的NSString boundingRectWithSize:...函数,它会以与NSAttributeString相同的方式请求一个attributes数组。 如果我不得不猜测,iOS 7中这个新的NSString函数仅仅是iOS 6的NSAttributeString函数的一个包装。

在那个笔记上,如果你只支持iOS 6和iOS 7,那么我肯定会把你所有的NSString的sizeWithFont:...改成NSAttributeString的boundingRectWithSize 。 如果你碰巧有一个奇怪的multithreading的情况下,它会节省你很多头痛! 以下是我如何转换NSString的sizeWithFont:constrainedToSize: ::

曾经是:

 NSString *text = ...; CGFloat width = ...; UIFont *font = ...; CGSize size = [text sizeWithFont:font constrainedToSize:(CGSize){width, CGFLOAT_MAX}]; 

可以replace为:

 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); 

如果你想兼容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这样,也许你需要做一些修改,取决于你想要的东西。 ;)

对于iOS7,请replace:

 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; 

您可以使用:

 UIFont *font = [UIFont boldSystemFontOfSize:16]; CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300) options:NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName: font} context:nil]; CGSize stringSize= new.size; 

如果你的目标是iOS 6.0+,你仍然可以使用sizeWithFont:constrainedToSize:lineBreakMode: 只要确保项目的iOS Deployment Target设置为6.0,编译器就不会给你这些警告。

(您可以通过点击“信息”部分中的蓝色项目选项卡(通常位于左侧的项目导航窗格中)来find它)。

如果您只定位iOS 7.0以上,则应使用新的方法boundingRectWithSize:options:attributes:context

你可以在这里find这个新方法的苹果文档。

boundingRectWithSize:options:attributes:context有问题,如果String包含“\ 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));