在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:你就可以了。

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