简体   繁体   English

在iOS 7弃用后如何替换sizeWithFont

[英]how to replace sizeWithFont after it is deprecated on iOS 7

I got an old project, and the code is using sizeWithFont. 我有一个旧项目,并且代码正在使用sizeWithFont。 I got an warning from xcode saying it is first deprecated in iOS 7, and asked me to replace it with 我从xcode收到警告,说它在iOS 7中已被弃用,并要求我将其替换为

(CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context

I got two questions: 我有两个问题:

I. if I intend not to change it, what whould happen? I.如果我不打算更改它,那又会怎样? Will it crash my app, or just bypass the deprecated API? 它会崩溃我的应用程序,还是只是绕过已弃用的API?

II. 二。 I wanted to use the suggested API, but I am confused it is asking for a CGSize paramter and returning a CGRect, while my old project just needs to return a CGSize. 我想使用建议的API,但感到困惑的是它要求CGSize参数并返回CGRect,而我的旧项目只需要返回CGSize。 If I already got the CGSize, why I need the rect again? 如果我已经有了CGSize,为什么还要再次使用rect? Please correct me and give code using the new API. 请更正我,并使用新的API给出代码。 Thanks a lot! 非常感谢!

EDIT: 编辑:

I have checked the answer in Replacement for deprecated sizeWithFont: in iOS 7? 我已经检查了iOS 7中过时的sizeWithFont:替换中的答案吗?

I will do a self-answer to compare two solutions. 我将做一个自我回答,比较两个解决方案。

Another quesiton I have is: 我有另一个问题:

I notice there is a [self setNumberOfLines:1]; 我注意到有一个[self setNumberOfLines:1]; , should I keep it or I can delete it? ,我应该保留它还是可以删除它? It does not impact anything in my code for now, but I don't know other situations, aka 'multiple line' situlation. 目前它不会影响我的代码中的任何内容,但是我不知道其他情况,也就是“多行”情况。

Old legacy code: 旧的旧版代码:

@implementation UILabel (dynamicSize)
-(CGFloat)expectedWidth{
    [self setNumberOfLines:1];

    CGSize maximumLabelSize = CGSizeMake(9999,self.frame.size.height);

    CGSize expectedLabelSize = [[self text] sizeWithFont:[self font]
                                       constrainedToSize:maximumLabelSize
                                           lineBreakMode:[self lineBreakMode]];
    return expectedLabelSize.width;
}
@end

I will do a self-answer to compare two solutions from Replacement for deprecated sizeWithFont: in iOS 7? 我将做一个自我回答,以比较iOS 7中过时的sizeWithFont中来自Replacement的两个解决方案

BTW I am not sure if I need to setNumberOfLines, so I will set it to no limit 顺便说一句,我不确定是否需要setNumberOfLines,所以我将其设置为无限制

[self setNumberOfLines:0];

One solution is 一种解决方案是

CGSize size = [[self text] sizeWithAttributes:@{NSFontAttributeName: [self font]}];

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

Another one: 另一个:

NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:[self text]
                                                                     attributes:@{NSFontAttributeName: [self font]}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){CGFLOAT_MAX, CGFLOAT_MAX} // be careful here
                                           options:NSStringDrawingUsesLineFragmentOrigin
                                           context:nil];
CGSize size = rect.size;
CGSize adjustedSize = CGSizeMake(ceilf(size.width), ceilf(size.height));

Both solution gives the same result as the deprecated API. 两种解决方案的结果都与弃用的API相同。 To summerize, I use sizeWithAttributes because it is simpler. 总结一下,我使用sizeWithAttributes,因为它更简单。

However one thing to mention that: 但是要提到的一件事是:

the answer in Replacement for deprecated sizeWithFont: in iOS 7? iOS 7中过时的sizeWithFont替换中的答案 uses kinds of (CGSize){width, CGFLOAT_MAX}]; 使用(CGSize){width, CGFLOAT_MAX}]; as the size parameter, 作为大小参数,

but I tested if I use it like (CGSize){self.bounds.size.width, CGFLOAT_MAX}]; 但是我测试了是否使用了(CGSize){self.bounds.size.width, CGFLOAT_MAX}]; The result is not correct, the calculated width is less than the other solution. 结果不正确,计算出的宽度小于其他解决方案。

If I use (CGSize){CGFLOAT_MAX, CGFLOAT_MAX} , I will get the same result as the other answer. 如果使用(CGSize){CGFLOAT_MAX, CGFLOAT_MAX} ,我将得到与其他答案相同的结果。 Test your code before you decide choosing a solution. 在决定选择解决方案之前,请测试您的代码。

You can provide the CGFLOAT_MAX in width if your label need to change width as per text size while put CGFLOAT_MAX in height if you want hight as per text in label. 如果您的标签需要根据文本大小更改宽度,则可以提供CGFLOAT_MAX的宽度,而如果您希望根据标签中的文本高度更改,则可以提供CGFLOAT_MAX的高度。 The other param will be static. 另一个参数将是静态的。

NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:[self text]

//If Height is dynamic and width is fix, Eg.150 width fix, and height dynamic
CGRect rect = [attributedText boundingRectWithSize:(CGSize){150, CGFLOAT_MAX}
                                       options:NSStringDrawingUsesLineFragmentOrigin
                                       context:nil];

              // OR

//If width is dynamic and Height is  fix, Eg.150 Height fix, and width dynamic
CGRect rect = [attributedText boundingRectWithSize:(CGSize){CGFLOAT_MAX,150}
                                       options:NSStringDrawingUsesLineFragmentOrigin
                                       context:nil];

You will get dynamic width, height as per your label size required. 您将根据需要的标签尺寸获得动态的宽度,高度。

There are miss concepts about the two methods, if you are tring to get the size of a text container such as UITexView or UILabel , this methods only give you the space occupied by the text, and not by the view, with multiple rows this can lead to clipped text, for instante UITextView contains some padding, those methods doesn't take into account that. 关于这两种方法,有一些遗漏的概念,如果您正试图获取文本容器(如UITexViewUILabel ,则此方法仅为您提供文本所占据的空间,而不是视图所占据的空间,并且可以多行导致剪切的文本,例如, UITextView包含一些填充,这些方法没有考虑到这一点。
Instead calling -sizeToFit on the text view after adding the text gives you the real size. 在添加文本后,在文本视图上调用-sizeToFit可以提供实际大小。
About your questions: 关于您的问题:

  1. Deprecated means that could broke in future releases of iOSes, usually is not a big deal to keep them for a while, but I strongly suggest to change them, to update your code, pay attention that if you are deploying an iOS target that doens't include the new API your app will crash in that specific iOS version 弃用意味着可能会在将来的iOS版本中中断,保留一段时间通常并不重要,但是我强烈建议您对其进行更改,以更新代码,请注意,如果您部署的iOS目标包括新API,您的应用将在该特定iOS版本中崩溃
  2. Just use the .size inside the CGRect struct. 只需使用.size里面CGRect结构。
  3. This is the maximum number of lines possible, if it doens't fit UILabel will cut the text with rule selected in the -linebreakMode , use 0 to have no restriction 这是可能的最大行数,如果不合适, UILabel将使用-linebreakMode选择的规则剪切文本,使用0表示没有限制

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM