在iOS 7中替换已弃用的sizeWithFont:

本文翻译自:Replacement for deprecated sizeWithFont: in iOS 7?

In iOS 7, sizeWithFont: is now deprecated. 在iOS 7中, sizeWithFont:现已弃用。 How do I now pass in the UIFont object into the replacement method sizeWithAttributes: ? 我现在如何将UIFont对象传递给替换方法sizeWithAttributes: :?


#1楼

参考:https://stackoom.com/question/1HICm/在iOS-中替换已弃用的sizeWithFont


#2楼

Use sizeWithAttributes: instead, which now takes an NSDictionary . 使用sizeWithAttributes:相反,它现在采用NSDictionary Pass in the pair with key UITextAttributeFont and your font object like this: 使用键UITextAttributeFont和您的字体对象传递一对,如下所示:

CGSize size = [string sizeWithAttributes:
    @{NSFontAttributeName: [UIFont systemFontOfSize:17.0f]}];

// Values are fractional -- you should take the ceilf to get equivalent values
CGSize adjustedSize = CGSizeMake(ceilf(size.width), ceilf(size.height));

#3楼

As you can see sizeWithFont at Apple Developer site it is deprecated so we need to use sizeWithAttributes . 正如您在Apple Developer站点上看到的sizeWithFont ,它已被弃用,因此我们需要使用sizeWithAttributes

#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

NSString *text = @"Hello iOS 7.0";
if (SYSTEM_VERSION_LESS_THAN(@"7.0")) {
    // code here for iOS 5.0,6.0 and so on
    CGSize fontSize = [text sizeWithFont:[UIFont fontWithName:@"Helvetica" 
                                                         size:12]];
} else {
    // code here for iOS 7.0
   CGSize fontSize = [text sizeWithAttributes: 
                            @{NSFontAttributeName: 
                              [UIFont fontWithName:@"Helvetica" size:12]}];
}

#4楼

Create a function that takes a UILabel instance. 创建一个带有UILabel实例的函数。 and returns CGSize 并返回CGSize

CGSize constraint = CGSizeMake(label.frame.size.width , 2000.0);
// Adjust according to requirement

CGSize size;
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){

    NSRange range = NSMakeRange(0, [label.attributedText length]);

    NSDictionary *attributes = [label.attributedText attributesAtIndex:0 effectiveRange:&range];
    CGSize boundingBox = [label.text boundingRectWithSize:constraint options: NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size;

    size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height));
}
else{
    size = [label.text sizeWithFont:label.font constrainedToSize:constraint lineBreakMode:label.lineBreakMode];
}

return size;

#5楼

I believe the function was deprecated because that series of NSString+UIKit functions ( sizewithFont:... , etc) were based on the UIStringDrawing library, which wasn't thread safe. 我相信该函数已被弃用,因为NSString+UIKit函数系列( sizewithFont:...等)基于UIStringDrawing库,它不是线程安全的。 If you tried to run them not on the main thread (like any other UIKit functionality), you'll get unpredictable behaviors. 如果您尝试不在主线程上运行它们(就像任何其他UIKit功能一样),您将获得不可预测的行为。 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 NSAttributedString . 这就是为什么在iOS 6中,他们为NSAttributedString引入了boundingRectWithSize:...方法。 This was built on top of the NSStringDrawing libraries and is thread safe. 它建立在NSStringDrawing库之上,并且是线程安全的。

If you look at the new NSString boundingRectWithSize:... function, it asks for an attributes array in the same manner as a NSAttributeString . 如果查看新的NSString boundingRectWithSize:...函数,它会以与NSAttributeString相同的方式请求属性数组。 If I had to guess, this new NSString function in iOS 7 is merely a wrapper for the NSAttributeString function from iOS 6. 如果我不得不猜测,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 sizeWithFont:... to the NSAttributeString boundingRectWithSize . 在这方面,如果你只支持iOS 6和iOS 7,那么我肯定会将你的所有NSString sizeWithFont:...更改为NSAttributeString 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 sizeWithFont:constrainedToSize: : 这是我如何转换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 ); 在iOS 7及更高版本中,此方法返回小数大小(在返回的CGRect的大小组件中); to use a returned size to size views, you must use raise its value to the nearest higher integer using the ceil function. 要使用返回的大小来调整视图大小,必须使用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);

#6楼

I created a category to handle this problem, here it is : 我创建了一个类别来处理这个问题,这里是:

#import "NSString+StringSizeWithFont.h"

@implementation NSString (StringSizeWithFont)

- (CGSize) sizeWithMyFont:(UIFont *)fontToUse
{
    if ([self respondsToSelector:@selector(sizeWithAttributes:)])
    {
        NSDictionary* attribs = @{NSFontAttributeName:fontToUse};
        return ([self sizeWithAttributes:attribs]);
    }
    return ([self sizeWithFont:fontToUse]);
}

This way you only have to find/replace sizeWithFont: with sizeWithMyFont: and you're good to go. 这样你只需要找到/替换sizeWithFont: with sizeWithMyFont:你就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章