替换已弃用的“sizeWithFont:constrainedToSize:lineBreakMode”的正确语法

Posted

技术标签:

【中文标题】替换已弃用的“sizeWithFont:constrainedToSize:lineBreakMode”的正确语法【英文标题】:Correct syntax for replacement of deprecated "sizeWithFont:constrainedToSize:lineBreakMode" 【发布时间】:2014-10-20 20:18:34 【问题描述】:

我已经接受了整整 10 天的 ios/Objective-C 培训(几乎没有其他编码课程),因此在这方面远远超出了我的水平,但我继承了一个巨大的 iOS 应用程序,我现在正在为此工作负责从以 iOS6 为中心升级到以 iOS 7 为中心。我正在尝试清理 Xcode 中的所有警告,但根本无法弄清楚这一点。我已经搜索了几天并阅读了关于 SO 的所有答案,但没有一个能准确回答我的问题(尽管有些人帮助我更接近,对此我深表感激)。

我知道“sizeWithFont:constrainedToSize:lineBreakMode:”已被弃用,需要替换为“boundingRectWithSize:options:attributes:context:”,但对于我的一生,我无法弄清楚如何转换一些现有的从旧方法到新方法的代码。如果我能理顺这一点,它将清除 Xcode 中的 35 个其他警告,因为在许多其他地方都使用了相同的已弃用方法。

我所做的研究提供了一些如何使用新方法的示例,但它似乎以不同的方式使用(CGRect 和 CGSize),Apple 的文档只是将我发送到“一个无限循环”中。对于我的“选项:”,Apple 说要使用段落样式选项,但这些选项与可用于已弃用样式的选项完全不同(其中一半也已弃用)。例如,他们说如果您不指定样式,它将使用默认的段落样式,但我不知道这些属性是什么,也不知道在哪里可以找到它们来验证它们是什么。如果我指定了一种样式,它必须是“this one”或“that one”,但是如果我使用其中一个,我也必须使用“this other one”,但是除非我的行,否则这些都不会生效休息模式是“又一个”,但“又一个”的风格不是我需要使用的。

因此,我无法弄清楚如何将旧代码中的属性专门转换为在非弃用方法中产生完全相同结果的代码。我想我已经很接近了,但是无法正确使用“NSLineBreakByClipping”来转换为新方法的语法而不会出现硬错误。错误出现在“width=expectedLabelSize1.width”行中,并显示“'struct CGRect' 中没有名为“width”的成员”。如果我将 CGRect 更改为 CGSize,就像在原始代码中一样,我会在关于初始化具有不兼容类型的表达式的特定行上收到不同的错误。

这里是原始代码:

        int width = 0;
    if([surveyType isEqualToString:@"Site Survey"])

//calculate the expected width of the survey label...
        CGSize maximumLabelSize = CGSizeMake(165,16);
        CGSize expectedLabelSize1 = [surveyName sizeWithFont:[UIFont systemFontOfSize:9.0] constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByClipping];
        width=expectedLabelSize1.width;
        if(width > 165)
            width=165;
        

这就是我能够拼凑起来的东西:

//calculate the expected width of the survey label...
        CGSize maximumLabelSize = CGSizeMake(165,16);
        CGRect expectedLabelSize1 = [surveyName boundingRectWithSize:maximumLabelSize
                                                  options:(NSStringDrawingUsesLineFragmentOrigin |
                                                           NSStringDrawingTruncatesLastVisibleLine | NSLineBreakByWordWrapping)
                                               attributes:@NSFontAttributeName: [UIFont systemFontOfSize:9.0]
                                                  context:nil];

        width=expectedLabelSize1.width;
        if(width > 165)
            width=165;
        

显然,我真的不知道我在这里做什么,所以我希望有人能告诉我如何将旧方法转换为新方法,并且不会在此过程中丢失任何功能或格式。如果我最初拥有的 NSLineBreakModeByClipping 属性似乎不再是可用的属性或选项,我该如何合并它?

谢谢!!!

编辑:我很抱歉,但我刚刚意识到我遗漏了一些可能有助于解释我遇到的错误之一的代码。我省略了上面的前两行,其中变量“width”被初始化为整数。整个“标签大小计算”代码是一个更大的“if”语句的一部分,但唯一让我适合的部分是这篇文章所涉及的不推荐使用的方法。无论如何,由于 CGRect 中没有处理“宽度”,因此 CGRect 方法(width=expectedLabelSize1.width)之后的下一行会生成上面关于“宽度”不是结构成员的错误。现在我明白了,但我不知道如何将“width”属性添加到 CGRect 结构中。我所拥有的整体方法(boundingRectWithSize:options:attributes:context:) 似乎是“干净的”,因为它本身不会产生任何错误,但它没有解决“width”或 NSLineBreakModeByClipping 问题。这就是我遇到错误的地方(对于缺少的“宽度”变量),并且我迷失了如何将 NSLineBreakModeByClipping 合并到新方法语法中。

【问题讨论】:

【参考方案1】:

使用 UILabel sizeThatFits 更简单

例如。

CGSize maximumLabelSize = CGSizeMake(CGFLOAT_MAX,16);
CGSize expectedLabelSize1 = [surveyName sizeThatFits:max];
width=expectedLabelSize1.width;
if(width > 165)
  width=165;

另见http://doing-it-wrong.mikeweller.com/2012/07/youre-doing-it-wrong-2-sizing-labels.html

【讨论】:

如果您使用像layoutSubviews 这样的方法,这非常有用。如果你在一个类/静态方法中,那么使用boundingRectWithSize:options:attributes:context: 是最干净的。 谢谢,railwayparade,但在这种情况下使用此方法不起作用。代码中的“surveyName”对象是一个 NSString 对象。我收到“NSString 没有可见的@interface 声明选择器 sizeThatFits:”的错误。据我所知,这意味着该方法不是 NSString 类的一部分,因此不能使用。此代码生成的“标签”是 PDF 封面上的文本标签,而不是 UI 上的按钮。这有帮助吗?【参考方案2】:

以下是我最近执行文本大小调整的方法:

- (CGSize)textSizeWithBoundingWidth:(CGFloat)boundingWidth attributes:(NSDictionary *)attributes

    CGSize boundingSize = (CGSize).width = boundingWidth,.height = 0;
    NSStringDrawingOptions options = (NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine);
    CGRect textBoundingRect = [self boundingRectWithSize:boundingSize options:options attributes:attributes context:nil];

    return ((CGSize).width = CGRectGetMaxX(rect),.height = CGRectGetMaxY(rect))

您还需要传入一个文本属性字典。对于您想要的两个(字体和 lineBreakMode),您可以像这样传递它们:

NSMutableDictionary* attributesDictionary = [NSMutableDictionary dictionary];

[attributesDictionary setObject:self.font forKey:NSFontAttributeName];

NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setLineBreakMode:self.lineBreakMode];

[attributesDictionary setObject:style forKey:NSParagraphStyleAttributeName];

【讨论】:

以上是关于替换已弃用的“sizeWithFont:constrainedToSize:lineBreakMode”的正确语法的主要内容,如果未能解决你的问题,请参考以下文章

Snapkit 常量替换已弃用的 .priorityMedium() .priorityHigh() .priorityLow()?

替换 Java Awt 已弃用的方法

什么是已弃用的 getSupportLoaderManager() 的适当替换?

替换已弃用的 `keypress` DOM 事件

jQuery:替换已弃用的“.load()”? [复制]

用 QuerydslJpaPredicateExecutor 替换已弃用的 QuerydslJpaRepository 失败