12

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

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

4

3 回答 3

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. 然后我们从该矩形中获取高度参数。
  3. 在 iOS 7 中,此方法返回小数。我们需要一个圆形的图形。ceilf 对此有所帮助。
  4. 我们为返回值添加了一个额外的单位。

这是如何使用它

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

您可以使用该高度进行布局计算。

于 2013-12-10T10:26:08.110 回答
5

@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
于 2016-01-20T15:18:32.643 回答
0

TTTAttributedLabel调用中有一个方法

+ (CGSize)sizeThatFitsAttributedString:withConstraints:limitedToNumberOfLines:

基本上,这个方法使用一些Core Text API来计算高度,关键函数是

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

我认为,也被

- (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;
于 2018-03-09T13:18:03.530 回答