【问题标题】:how to replace sizeWithFont after it is deprecated on iOS 7在 iOS 7 上弃用 sizeWithFont 后如何替换它
【发布时间】:2015-06-18 13:46:29
【问题描述】:

我有一个旧项目,代码使用 sizeWithFont。我从 xcode 收到警告说它在 iOS 7 中首先被弃用,并要求我用

替换它

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

我有两个问题:

我。如果我不打算改变它,会发生什么?它会导致我的应用崩溃,还是只是绕过已弃用的 API?

二。我想使用建议的 API,但我很困惑它要求一个 CGSize 参数并返回一个 CGRect,而我的旧项目只需要返回一个 CGSize。如果我已经获得了 CGSize,为什么我还需要 rect 呢?请纠正我并使用新的 API 提供代码。非常感谢!

编辑:

我已经检查了Replacement for deprecated sizeWithFont: in iOS 7?的答案

我会做一个自我回答来比较两个解决方案。

我的另一个问题是:

我注意到有一个[self setNumberOfLines:1];,我应该保留它还是删除它?目前它不会影响我的代码中的任何内容,但我不知道其他情况,即“多行”情况。

旧代码:

@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

【问题讨论】:

  • 对于您的第一个问题,在 Apple 删除旧代码之前,您的应用程序不会崩溃。短期内不会轻易发生的事情。对于sizeWithFont:constrainedToSize: 的使用,请参阅重复的问题。
  • 谢谢,我正在看
  • @rckoenes 我用我挖掘出来的东西更新了我的问题。我想将其发布为答案,但您将其关闭。我们可以做些什么来突出我的发现?
  • @wingzeor 我重新打开了你的问题。
  • @rckoenes 谢谢,已更新。顺便说一句,我注意到有[self setNumberOfLines:1]; 我应该保留它我可以删除它吗?

标签: ios uilabel


【解决方案1】:

关于这两种方法有一些错误的概念,如果你想得到一个文本容器的大小,比如UITexViewUILabel,这个方法只给你文本占用的空间,而不是由查看,如果有多行,这可能会导致文本被剪裁,因为即时 UITextView 包含一些填充,这些方法没有考虑到这一点。
而是在添加文本后在文本视图上调用 -sizeToFit 以获得实际大小。
关于您的问题:

  1. Deprecated 表示可能会在未来的 iOS 版本中崩溃,通常保留一段时间并没有什么大不了的,但我强烈建议更改它们,更新您的代码,请注意,如果您正在部署 iOS 目标不包含新 API,您的应用将在该特定 iOS 版本中崩溃
  2. 只需在CGRect 结构中使用.size
  3. 这是可能的最大行数,如果不适合UILabel 将使用-linebreakMode 中选择的规则剪切文本,使用0 表示没有限制

【讨论】:

  • 感谢您的回答,但我已经发布了所有解决方案并进行了比较。对于您的答案 #2,self.bounds.size 是不够的。如果您使用 boundingRectWithSize,它应该是 {CGFLOAT_MAX, CGFLOAT_MAX}。我最后选择了sizeWithAttributes
【解决方案2】:

如果您的标签需要根据文本大小更改宽度,您可以提供 CGFLOAT_MAX 的宽度,而如果您希望根据标签中的文本设置高度,则将 CGFLOAT_MAX 设置为高度。另一个参数将是静态的。

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];

您将根据所需的标签尺寸获得动态宽度、高度。

【讨论】:

  • 我很欣赏你的回答,但与我的相比,你在如何选择尺寸方面缺乏一些精确性和解释。我已经自己回答过了,所以我希望你能通过答案。
【解决方案3】:

我会做一个自我回答来比较Replacement for deprecated sizeWithFont: in iOS 7?的两个解决方案

顺便说一句,我不确定是否需要 setNumberOfLines,所以我将其设置为无限制

[self setNumberOfLines:0];

一个解决方案是

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));

另一个:

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));

两种解决方案的结果都与已弃用的 API 相同。总结一下,我使用 sizeWithAttributes 因为它更简单。

不过有一件事要提一下:

Replacement for deprecated sizeWithFont: in iOS 7? 中的答案使用各种(CGSize){width, CGFLOAT_MAX}]; 作为大小参数,

但我测试了我是否像(CGSize){self.bounds.size.width, CGFLOAT_MAX}];那样使用它 结果不正确,计算出的宽度小于其他解。

如果我使用(CGSize){CGFLOAT_MAX, CGFLOAT_MAX},我将得到与其他答案相同的结果。在决定选择解决方案之前测试您的代码。

【讨论】:

    猜你喜欢
    • 2013-09-24
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多