【问题标题】:Replacement for sizeWithFont:ForWidth:lineBreakMode:替换 sizeWithFont:ForWidth:lineBreakMode:
【发布时间】:2013-09-27 19:31:45
【问题描述】:

我用来确定打印字符串布局以创建复杂 pdf 文档的许多方法在 iOS7 中已被弃用。文档调用了相同的方法来替换所有已弃用的 sizeWithFont 方法:

boundingRectWithSize:options:attributes:

这对sizeWithFont:ConstrainedTosize:lineBreakMode 来说很好,但如果我只希望我的字符串在一行上怎么办?我不知道使用什么来设置最大高度,所以我没有一个矩形可以作为第一个参数的值。

这是我在限制给定尺寸时所拥有的。

CGFloat maxHeightAllowable = _maxHeight;
CGSize issueTitleMaxSize = CGSizeMake(_issueListTitleColWidth - (kColumnMargin *2), maxHeightAllowable);
NSDictionary *issueTitleAttributes = [NSDictionary dictionaryWithObjectsAndKeys:_bodyFont, NSFontAttributeName, nil];
CGRect issueTitleRect = CGRectIntegral([issueTitleText boundingRectWithSize:issueTitleMaxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:issueTitleAttributes context:nil]);
CGSize issueTitleSize = issueTitleRect.size;

如果我不知道 maxHeight,或者实际上,一条线的高度正是我想要找出的,我将如何使用相同的方法?

我明白他们为什么要推动 NSAttributed 字符串和自动布局的兼容性,但为什么要弃用这些?就我而言,替换现在需要 4 或 5 步,而以前是 1 或 2 步。

使用 font 的 lineHeight 属性,按照 T 先生的建议,我将这些方法放在一个类别中,大大简化了我的替换。

#import "NSString+SizingForPDF.h"

@implementation NSString (SizingForPDF)

-(CGSize)integralSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)maxSize
{
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
    CGRect rect = CGRectIntegral([self boundingRectWithSize:maxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:attributes context:nil]);
    return rect.size;
}

-(CGSize)integralSizeWithFont:(UIFont *)font maxWidth:(CGFloat)maxWidth numberOfLines:(NSInteger)lines
{
    if (lines == 0) {
        lines = 1;
    }
    NSDictionary *attributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
    CGFloat height = font.lineHeight * lines;
    CGSize maxsize = CGSizeMake(maxWidth, height);
    CGRect rect = CGRectIntegral([self boundingRectWithSize:maxsize options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading attributes:attributes context:nil]);
    return rect.size;
}

@end

【问题讨论】:

    标签: nsstring ios7 deprecated


    【解决方案1】:

    如果你只是在寻找一行的高度,你不能只使用你字体的lineHeight 属性吗?我用它来设置标签的高度或正确预测元素的高度,没有任何问题。我不确定pdf文档在这方面是否有所不同。

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

    请注意,如果您只支持 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}];
    

    可以很容易地替换为:

    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;
    

    请注意文档中提到的:

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

    所以要提取计算出的高度或宽度以用于调整视图大小,我会使用:

    CGFloat height = ceilf(size.height);
    CGFloat width  = ceilf(size.width);
    

    【讨论】:

    • 你的方法和我的差不多,只是我使用 CGRectIntegral 宏将值钳制为整数。我从没想过要查看字体的行高。这就是我的答案。我用它在一个类别中创建了几个新方法,更容易替换我以前的代码。
    • LineBreakMode 被 NSParagraphStyle 属性替换,该属性可以添加到属性字典中。有关如何执行此操作的详细示例,请参阅 stackoverflow.com/a/26894770/338468
    猜你喜欢
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多