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

Jam*_*ang 320 objective-c deprecated ios7

在iOS 7中,sizeWithFont:现已弃用.我现在如何将UIFont对象传递给替换方法sizeWithAttributes:

Jam*_*ang 521

使用sizeWithAttributes:相反,现在需要的NSDictionary.使用密钥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));
Run Code Online (Sandbox Code Playgroud)

  • 当使用`NSString`和`UILabel`(不是总是如此,但经常如此),为了防止重复的代码/等,你也可以用`label.font`替换`[UIFont systemFontOfSize:17.0f]` - 通过引用现有数据来帮助代码维护,而不是多次键入或在整个地方引用常量等 (60认同)
  • @Pedroinpeace你会使用`boundingRectWithSize:options:attributes:context:`代替,在大多数情况下传入`CGSizeMake(250.0f,CGFLOAT_MAX)`. (12认同)
  • 要注意sizeWithAttributes的其他内容:不是100%等效.sizeWithFont用于将大小向上舍入为整数(像素)值.建议在合成高度/宽度上使用ceilf,否则如果将其用于位置计算,可能会出现模糊的假象(尤其是非视网膜硬度). (9认同)
  • @toblerpwn标签可能不存在,你正在尝试计算理论标签. (8认同)
  • 我如何使用此示例来获取带有固定宽度(例如250)的标签的size.height?或者,如果它与autolatyout女巫的标签占据宽度的过程,我去景观模式. (5认同)
  • 无需为天花板引入另一个变量.`size = CGSizeMake(ceilf(size.width),ceilf(size.height));` (3认同)

Mr.*_*. T 172

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

如果查看新NSString boundingRectWithSize:...函数,它会以与a相同的方式请求属性数组NSAttributeString.如果我不得不猜测,NSStringiOS 7中的这个新功能仅仅是NSAttributeStringiOS 6中的功能包装.

关于这一点,如果你只支持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}];
Run Code Online (Sandbox Code Playgroud)

可以替换为:

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;
Run Code Online (Sandbox Code Playgroud)

请注意文档提到:

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

因此,要拉出用于调整视图大小的计算高度或宽度,我会使用:

CGFloat height = ceilf(size.height);
CGFloat width  = ceilf(size.width);
Run Code Online (Sandbox Code Playgroud)

  • 很棒,提到使用ceilf().没有其他地方提到过,我的体型总是略微过小.谢谢! (5认同)
  • @Nirav我没有看到任何关于弃用的提及.你能指点我说它被弃用的地方吗?谢谢!(https://developer.apple.com/library/ios/documentation/uikit/reference/NSAttributedString_UIKit_Additions/Reference/Reference.html) (2认同)
  • 也许@Nirav意味着它不适用于iOS 6中的*NSString*(在答案中间接提到)? (2认同)

Ayu*_*ush 29

正如您sizeWithFont在Apple Developer网站上看到的那样,它已被弃用,因此我们需要使用它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]}];
}
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,最好使用`[NSObject respondsToSelector:]`方法,如下所示:http://stackoverflow.com/a/3863039/1226304 (17认同)

Rom*_*om. 16

我创建了一个类别来处理这个问题,这里是:

#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]);
}
Run Code Online (Sandbox Code Playgroud)

这样,您只需要查找/替换sizeWithFont:sizeWithMyFont:,你是好去.


小智 10

在iOS7中,我需要逻辑来返回tableview的正确高度:heightForRowAtIndexPath方法,但sizeWithAttributes总是返回相同的高度而不管字符串长度,因为它不知道它将被放入固定宽度的表格单元格中.我发现这对我很有用,并考虑到表格单元格的宽度来计算正确的高度!这是基于T先生的上述答案.

NSString *text = @"The text that I want to wrap in a table cell."

CGFloat width = tableView.frame.size.width - 15 - 30 - 15;  //tableView width - left border width - accessory indicator - right border width
UIFont *font = [UIFont systemFontOfSize:17];
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;
size.height = ceilf(size.height);
size.width  = ceilf(size.width);
return size.height + 15;  //Add a little more padding for big thumbs and the detailText label
Run Code Online (Sandbox Code Playgroud)


bit*_*and 7

使用动态高度的多行标签可能需要其他信息才能正确设置大小.您可以将sizeWithAttributes与UIFont和NSParagraphStyle一起使用来指定字体和换行模式.

您将定义段落样式并使用如下的NSDictionary:

// set paragraph style
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:NSLineBreakByWordWrapping];
// make dictionary of attributes with paragraph style
NSDictionary *sizeAttributes        = @{NSFontAttributeName:myLabel.font, NSParagraphStyleAttributeName: style};
// get the CGSize
CGSize adjustedSize = CGSizeMake(label.frame.size.width, CGFLOAT_MAX);

// alternatively you can also get a CGRect to determine height
CGRect rect = [myLabel.text boundingRectWithSize:adjustedSize
                                                         options:NSStringDrawingUsesLineFragmentOrigin
                                                      attributes:sizeAttributes
                                                         context:nil];
Run Code Online (Sandbox Code Playgroud)

如果您正在寻找高度,可以使用CGSize'contatedSize'或CGRect作为rect.size.height属性.

有关NSParagraphStyle的更多信息,请访问:https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSParagraphStyle_Class/Reference/Reference.html


Kir*_*ela 6

// max size constraint
CGSize maximumLabelSize = CGSizeMake(184, FLT_MAX)

// font
UIFont *font = [UIFont fontWithName:TRADE_GOTHIC_REGULAR size:20.0f];

// set paragraph style
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;

// dictionary of attributes
NSDictionary *attributes = @{NSFontAttributeName:font,
                             NSParagraphStyleAttributeName: paragraphStyle.copy};

CGRect textRect = [string boundingRectWithSize: maximumLabelSize
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:attributes
                                     context:nil];

CGSize expectedLabelSize = CGSizeMake(ceil(textRect.size.width), ceil(textRect.size.height));
Run Code Online (Sandbox Code Playgroud)