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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18922252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:28:45  来源:igfitidea点击:

'sizeWithFont:constrainedToSize:lineBreakMode:'is deprecated:

iosxcodeuikitnstextview

提问by iSrini

Converting a project from iOS5.0 to iOS7 / iOS6 on Xcode 5. The code below is giving a compile time warning:

在 Xcode 5 上将项目从 iOS5.0 转换为 iOS7/iOS6。下面的代码给出了编译时警告:

'sizeWithFont:constrainedToSize:lineBreakMode:'is deprecated: first deprecated in ios 7.0 - Use - boundingRectWithSize:options:attribiutes:context

'sizeWithFont:constrainedToSize:lineBreakMode:' 已弃用:在 ios 7.0 中首次弃用 - 使用 - boundingRectWithSize:options:attributes: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;
    }

I tried some of the suggestion give elsewhere but nothing is up to rescue if some one can help by giving the corrections required in the code will be greatly appreciated.

我尝试了其他地方给出的一些建议,但如果有人可以通过提供代码中所需的更正来提供帮助,将不胜感激。

回答by Mr. T

I wouldn't just mask the deprecated function warning. They deprecated it for a reason. I believe the function was deprecated because that series of NSString+UIKit functions were based on the UIStringDrawing library, which wasn't thread safe. If you tried to run them not on the main thread (like any other UIKit functionality), you'll get unpredictable behaviors. In particular, if you ran the function on multiple threads simultaneously, it'll probably crash your app. This is why in iOS 6, they introduced a the boundingRectWithSize:...method for NSAttributedStrings. This was built on top of the NSStringDrawing libraries and is thread safe.

我不会只是掩盖已弃用的函数警告。他们出于某种原因不赞成使用它。我相信该函数已被弃用,因为该系列 NSString+UIKit 函数基于 UIStringDrawing 库,该库不是线程安全的。如果您尝试不在主线程上运行它们(像任何其他 UIKit 功能一样),您将获得不可预测的行为。特别是,如果您同时在多个线程上运行该函数,它可能会使您的应用程序崩溃。这就是为什么在 iOS 6 中,他们boundingRectWithSize:...为 NSAttributedStrings引入了一个方法。这是建立在 NSStringDrawing 库之上的,并且是线程安全的。

If you look at the new NSString boundingRectWithSize:...function, it asks for an attributes array in the same manner as a NSAttributeString. If I had to guess, this new NSString function in iOS 7 is merely a wrapper for the NSAttributeString function from iOS 6.

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

On that note, if you were only supporting iOS 6 and iOS 7, then I would definitely change all of your NSString's sizeWithFont:...to the NSAttributeString's boundingRectWithSize. It'll save you a lot of headache if you happen to have a weird multi-threading corner case! Here's how I converted NSString's sizeWithFont:constrainedToSize::

关于这一点,如果您只支持 iOS 6 和 iOS 7,那么我肯定会将您所有的 NSString 更改sizeWithFont:...为 NSAttributeString 的boundingRectWithSize. 如果您碰巧有一个奇怪的多线程角落案例,它将为您省去很多麻烦!这是我转换 NSString 的方法sizeWithFont:constrainedToSize:

What used to be:

曾经是什么:

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

Can be replaced with:

可以替换为:

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;

Please note the documentation mentions:

请注意文档中提到:

In iOS 7 and later, this method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must use raise its value to the nearest higher integer using the ceil function.

在 iOS 7 及更高版本中,此方法返回小数大小(在返回的 CGRect 的大小组件中);要使用返回的大小来调整视图的大小,您必须使用 ceil 函数将其值提高到最接近的更高整数。

So to pull out the calculated height or width to be used for sizing views, I would use:

因此,要提取用于调整视图大小的计算高度或宽度,我将使用:

CGFloat height = ceilf(size.height);
CGFloat width  = ceilf(size.width);

回答by Kjuly

If you want it compatible with both iOS7 and the versions below it, try this one (with ARC):

如果您希望它与 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
}

Note: It's just an example for your else-ifcase, maybe you need to do some modification depend on what you want it be. ;)

注意:这只是您的else-if情况的一个示例,也许您需要根据自己的需要进行一些修改。;)

回答by Dave Chambers

For iOS7, replace:

对于 iOS7,替换:

CGSize size = [tempPointStr sizeWithFont:self.lblHidden.font
                       constrainedToSize:self.lblHidden.frame.size
                           lineBreakMode:NSLineBreakByWordWrapping];

With:

和:

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;

回答by user3575114

You can use:

您可以使用:

UIFont *font = [UIFont boldSystemFontOfSize:16];

CGRect new = [string boundingRectWithSize:CGSizeMake(200, 300)
    options:NSStringDrawingUsesFontLeading 
    attributes:@{NSFontAttributeName: font} 
    context:nil];

CGSize stringSize= new.size;

回答by EckhardN

The boundingRectWithSize:options:attributes:context has the problem, that it does not calculates the height correctly if the String contains "\n" (line breaks). Therefore this code calculates the size for each line separately for a given width (inWidth):

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

回答by JRG-Developer

If you're targeting iOS 6.0+, you can still use sizeWithFont:constrainedToSize:lineBreakMode:. Just make sure that your project's iOS Deployment Targetis set for 6.0, and the compiler won't give you these warnings.

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

(You can find this by clicking on the blue project tab (usually at the top of the left, project navigator pane) within the "info" section).

(您可以通过单击“信息”部分中的蓝色项目选项卡(通常位于项目导航器窗格的左上方)来找到它)。

If you're only targeting iOS 7.0+, you should use the new method boundingRectWithSize:options:attributes:context.

如果您只针对 iOS 7.0+,则应使用新方法boundingRectWithSize:options:attributes:context

You can find the Apple docs on this new method here.

您可以在此处找到有关此新方法的 Apple 文档。