如何计算NSAttributedString的高度,给定宽度和行数?

时间:2013-09-19 06:53:05

标签: nsattributedstring

我想显示3行NSAttributedString。有没有办法根据宽度和线数找出所需的高度?

而且我不想创建UILabel来进行大小计算,因为我希望计算在后台线程中完成。

3 个答案:

答案 0 :(得分:6)

我想知道为什么这仍然没有答案。无论如何,这是对我有用的最快方法。

创建一个名为“Height”的NSAttributedString类别。这应该生成两个名为“NSAttributedString + Height。{h,m}”

的文件

在.h文件中:

@interface NSAttributedString (Height)  
-(CGFloat)heightForWidth:(CGFloat)width;  
@end  

在.m文件中:

-(CGFloat)heightForWidth:(CGFloat)width  
{  
    return ceilf(CGRectGetHeight([self boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX)
                                                    options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
                                                    context:nil])) + 1;  
}

以下是发生的事情:

  1. boundRectWithSize:options:context get是一个约束到传递给方法的宽度的矩形。 NSStringDrawingUsesLineFragmentOrigin选项告诉它期望多行字符串。
  2. 然后我们从那个矩形中获取height参数。
  3. 在iOS 7中,此方法返回小数。我们需要一个圆形的人物。 ceilf对此有所帮助。
  4. 我们在返回值中添加一个额外的单位。
  5. 以下是如何使用

    NSAttributedString *string = ...
    CGFloat height = [string heightForWidth:320.0f];
    

    您可以将该高度用于布局计算。

答案 1 :(得分:2)

@dezinezync的答案回答了问题的一半。您只需要计算具有给定宽度和行数的UILabel允许的最大大小。

首先,根据行数得到允许的高度:

let maxHeight = font.lineHeight * numberOfLines

然后根据标准计算您设置的文本的边界矩形:

let labelStringSize = yourText.boundingRectWithSize(CGSizeMake(CGRectGetWidth(self.frame), maxHeight),
            options: NSStringDrawingOptions.UsesLineFragmentOrigin,
            attributes: [NSFontAttributeName: font],
            context: nil).size

答案 2 :(得分:0)

+ (CGSize)sizeThatFitsAttributedString:withConstraints:limitedToNumberOfLines:中有一种名为

的方法

CGSize CTFramesetterSuggestFrameSizeWithConstraints( CTFramesetterRef framesetter, CFRange stringRange, CFDictionaryRef __nullable frameAttributes, CGSize constraints, CFRange * __nullable fitRange )

基本上,这种方法使用一些Core Text API来计算高度,关键功能是

- (CGRect)textRectForBounds:limitedToNumberOfLines:

我认为,

也使用了它

static UILabel *label; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ label = [UILabel new]; }); label.attributedText = givenAttributedString; CGRect rect = CGRectMake(0,0,givenWidth,CGFLOAT_MAX) CGFloat height = [label textRectForBounds:rect limitedToNumberOfLines:2].size.height;

这是一种解决方法,我认为有更好的方法......

{{1}}