在iOS 7中替换已弃用的-sizeWithFont:constrainedToSize:lineBreakMode :?


146

在iOS 7中,方法:

- (CGSize)sizeWithFont:(UIFont *)font
     constrainedToSize:(CGSize)size
         lineBreakMode:(NSLineBreakMode)lineBreakMode 

和方法:

- (CGSize)sizeWithFont:(UIFont *)font

不推荐使用。我该如何更换

CGSize size = [string sizeWithFont:font
                 constrainedToSize:constrainSize
                     lineBreakMode:NSLineBreakByWordWrapping];

和:

CGSize size = [string sizeWithFont:font];

2
替代方法是-sizeWithAttributes:
Holex 2013年

好吧,谢谢,但是,如何使用标签上的字体,如NSDIctionary?如果我的代码是这样的:sizeWithFont:customlabel.font;空问“ sizeWithAttributes:<#(NSDictionary *)#>”
user_Dennis_Mostajo 2013年

1
这里是你如何定义属性的官方文档:developer.apple.com/library/ios/documentation/UIKit/Reference/...
holex

Answers:


219

您可以尝试以下方法:

CGRect textRect = [text boundingRectWithSize:size
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:@{NSFontAttributeName:FONT}
                                 context:nil];

CGSize size = textRect.size;

只需将“ FONT”更改为“ [UIFont字体....]”


13
在哪里提到NSLineBreakByWordWrapping?你去了吗?
user4951 2013年

32
NSLineBreakByWordWrapping会在一个NSParagraphStyle。因此,例如:NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;在属性中,您需要添加NSParagraphStyleAttributeName: paragraphStyle.copy...
Florian Friedrich

1
@ffried在我的案例中添加了NSStyleBreakByWordWrapping以外的其他带有换行符的段落样式,导致仅计算了一行的大小……有什么想法吗?
manicaesar 2014年

9
不要忘记boundingRectWithSize:options:attributes:context:返回分数值。您需要分别进行ceil(textRect.size.height)ceil(textRect.size.width)以获取实际的高度/宽度。
Florian Friedrich

20
BOLIVIASize到底是什么?
JRam13,2014年

36

由于我们无法为所有大于4.3的iOS使用sizeWithAttributes,因此我们必须为7.0和以前的iOS编写条件代码。

1)解决方案1:

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
   CGSize size = CGSizeMake(230,9999);
   CGRect textRect = [specialityObj.name  
       boundingRectWithSize:size
                    options:NSStringDrawingUsesLineFragmentOrigin
                 attributes:@{NSFontAttributeName:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14]}
                    context:nil];
   total_height = total_height + textRect.size.height;   
}
else {
   CGSize maximumLabelSize = CGSizeMake(230,9999); 
   expectedLabelSize = [specialityObj.name sizeWithFont:[UIFont fontWithName:[AppHandlers zHandler].fontName size:14] constrainedToSize:maximumLabelSize lineBreakMode:UILineBreakModeWordWrap]; //iOS 6 and previous. 
   total_height = total_height + expectedLabelSize.height;
}

2)解决方案2

UILabel *gettingSizeLabel = [[UILabel alloc] init];
gettingSizeLabel.font = [UIFont fontWithName:[AppHandlers zHandler].fontName size:16]; // Your Font-style whatever you want to use.
gettingSizeLabel.text = @"YOUR TEXT HERE";
gettingSizeLabel.numberOfLines = 0;
CGSize maximumLabelSize = CGSizeMake(310, 9999); // this width will be as per your requirement

CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];

第一个解决方案是有时无法返回正确的高度值。因此请使用其他解决方案。这将完美地工作。

第二个选项很好,并且在没有条件代码的情况下在所有iOS中都可以正常运行。


1
为什么是230、999?您从哪里获得号码>
2013年

1
230可以是任何数字。它代表您想要标签的宽度。我宁愿用INFINITY或MAXFLOAT代替9999。
弗洛里安·弗里德里希

第二种解决方案是一种魅力。谢谢Nirav。
2014年

1
“ [AppHandlers zHandler]”给出错误。.“未声明的标识符”。怎么解决呢?
酒窝

9

这是简单的解决方案:

要求 :

CGSize maximumSize = CGSizeMake(widthHere, MAXFLOAT);
UIFont *font = [UIFont systemFontOfSize:sizeHere];

现在,因为constrainedToSizeusage:lineBreakMode:iOS 7.0中已弃用使用方式:

CGSize expectedSize = [stringHere sizeWithFont:font constrainedToSize:maximumSize lineBreakMode:NSLineBreakByWordWrapping];

现在,在更高版本的iOS 7.0中的用法将是:

// Let's make an NSAttributedString first
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:stringHere];
//Add LineBreakMode
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
[attributedString setAttributes:@{NSParagraphStyleAttributeName:paragraphStyle} range:NSMakeRange(0, attributedString.length)];
// Add Font
[attributedString setAttributes:@{NSFontAttributeName:font} range:NSMakeRange(0, attributedString.length)];

//Now let's make the Bounding Rect
CGSize expectedSize = [attributedString boundingRectWithSize:maximumSize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;

7

下面是两个简单的方法,它们将取代这两个不推荐使用的方法。

以下是相关参考资料:

如果您使用的是NSLineBreakByWordWrapping,则无需指定NSParagraphStyle,因为这是默认设置:https : //developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index。 html#// apple_ref / occ / clm / NSParagraphStyle / defaultParagraphStyle

您必须获取大小的上限,以匹配不赞成使用的方法的结果。 https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSString_UIKit_Additions/#//apple_ref/occ/instm/NSString/boundingRectWithSize:options:attributes:context

+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font {    
    CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: font}];
    return CGSizeMake(ceilf(size.width), ceilf(size.height));
}

+ (CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font constrainedToSize:(CGSize)size{
    CGRect textRect = [text boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:@{NSFontAttributeName: font}
                                     context:nil];
    return CGSizeMake(ceilf(textRect.size.width), ceilf(textRect.size.height));
}

6

在大多数情况下,我使用sizeWithFont:constrainedToSize:lineBreakMode:方法来估计UILabel的最小大小容纳其文本(尤其是当标签必须放在UITableViewCell内时)...

...如果这正是您的情况,则可以使用以下方法来简化:

CGSize size = [myLabel textRectForBounds:myLabel.frame limitedToNumberOfLines:mylabel.numberOfLines].size;

希望这会有所帮助。


5
Apple的文档说您不应直接调用此方法。
巴洛塔克

至少在iOS 7 SDK文档中未提及。
Rivera 2014年

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

3
欢迎使用StackOverFlow。不要再次发布相同的答案。如果您需要在答案中添加一些内容,请对答案进行评论或编辑。
Ramaraj T 2014年

好的..下次我会考虑的。谢谢您的建议。
user3575114 2014年

2

[可接受的答案在类别中效果很好。我正在覆盖不赞成使用的方法名称。这是一个好主意吗?在Xcode 6.x中似乎可以正常使用了]

如果您的部署目标为7.0或更高,则此方法有效。类别为NSString (Util)

NSString + Util.h

- (CGSize)sizeWithFont:(UIFont *) font;
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size;

NSString + Util.m

- (CGSize)sizeWithFont:(UIFont *) font {
    NSDictionary *fontAsAttributes = @{NSFontAttributeName:font};
    return [self sizeWithAttributes:fontAsAttributes];
}

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size {
    NSDictionary *fontAsAttributes = @{NSFontAttributeName:font};
    CGRect retVal = [self boundingRectWithSize:size
                                     options:NSStringDrawingUsesLineFragmentOrigin
                                  attributes:fontAsAttributes context:nil];
    return retVal.size;
}

0
UIFont *font = [UIFont fontWithName:@"Courier" size:16.0f];

NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
paragraphStyle.alignment = NSTextAlignmentRight;

NSDictionary *attributes = @{ NSFontAttributeName: font,
                    NSParagraphStyleAttributeName: paragraphStyle };

CGRect textRect = [text boundingRectWithSize:size
                                 options:NSStringDrawingUsesLineFragmentOrigin
                              attributes:attributes
                                 context:nil];

CGSize size = textRect.size;

来自两个答案1 + 2

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.