【问题标题】:Can't seem to calculate correct line-height of NSAttributedString for a UILabel似乎无法为 UILabel 计算正确的 NSAttributedString 行高
【发布时间】:2014-04-07 15:19:47
【问题描述】:

阅读this article from objc.io后,我正在使用NSAttributedString'sboundingRectWithSize:options:context:方法计算某些文本的预期高度

+(CGSize)postLabelSizeForPost:(ANKPost *)post
{
  CGFloat labelWidth = 220.0f;
  NSAttributedString *text = [BXTPostCell mutableAttributedStringForPost:post];
  NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
  CGRect boundingRect = [text boundingRectWithSize:CGSizeMake(labelWidth, CGFLOAT_MAX)
                                         options:options
                                         context:nil];
  CGFloat height = (CGFloat) (ceil(boundingRect.size.height));

  return CGSizeMake(labelWidth, height);
}

但是,当我使用此方法时,文本实际上并不适合此尺寸 - 尺寸始终太短。

起初,我认为问题出在表情符号字符上 - 但它似乎发生在应用程序中的许多 tableviewcells 上。

更新: 我和几个人谈过,听起来这个问题可能是boundingRectWithSize:options:context: 的一个潜在错误。我想出了一个解决方法:创建一个虚拟UILabel,赋予它与表格视图单元格中的UILabel 相同的属性(numberOfLines 等),然后使用sizeThatFits: 计算大小。可以肯定的是,这是一个 hack - 但它充分解决了我的问题。不过,我希望它更优雅!

【问题讨论】:

    标签: ios ios7 nsattributedstring


    【解决方案1】:

    我在尝试计算 UITextView 的属性文本大小时遇到​​了同样的效果。我遇到了this answer to another question

    诀窍是使用NSLayoutManager's usedRectForTextContainer:。巧妙的是,此方法不需要与 UITextView 结合使用。这意味着您可以在 mainThread 之外使用它,这是预先计算 UITableViewCell 高度的关键。

    我是这样使用它的:

    - (CGSize)rectForAttributedString:(NSAttributedString *)string withSize:(CGSize)theSize
    {
        if (!string || CGSizeEqualToSize(theSize, CGSizeZero)) {
            return CGSizeZero;
        }
    
        // setup TextKit stack
        NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:theSize];
        NSTextStorage *textStorage = [[NSTextStorage alloc] initWithAttributedString:string];
        NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
        [layoutManager addTextContainer:textContainer];
        [textStorage addLayoutManager:layoutManager];
    
        // query for size
        CGRect rect = [layoutManager usedRectForTextContainer:textContainer];
    
        return CGSizeMake(ceilf(rect.size.width), ceilf(rect.size.height));
    }
    

    为了方便起见,我创建了一个方便的方法来计算特定宽度的高度:

    - (CGFloat)textViewHeightForAttributedString:(NSAttributedString *)string withWidth:(CGFloat)width
    {
        return [self rectForAttributedString:string withSize:CGSizeMake(width, CGFLOAT_MAX)].height;
    }
    

    希望这会有所帮助。


    PS。我对整个编程有点陌生,所以如果我的代码可以优化,请告诉我。

    【讨论】:

      【解决方案2】:

      我想,你可能没有设置preferredMaxLayoutWidth

      此属性将约束设置为视图的最大宽度。

      【讨论】:

        猜你喜欢
        • 2017-03-06
        • 1970-01-01
        • 2021-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-27
        • 2020-05-03
        相关资源
        最近更新 更多