如何计算 NSAttributedString 的高度,给定宽度和行数?
Posted
技术标签:
【中文标题】如何计算 NSAttributedString 的高度,给定宽度和行数?【英文标题】:How to calculate the height of NSAttributedString, given width and number of lines? 【发布时间】:2013-09-19 06:53:05 【问题描述】:我想显示 3 行 NSAttributedString。有没有办法根据宽度和行数计算出所需的高度?
而且我不想创建 UILabel 来进行大小计算,因为我希望在后台线程中完成计算。
【问题讨论】:
在其他问题中有办法做到这一点 - ***.com/questions/42171468/… 【参考方案1】:我想知道为什么这仍然没有答案。无论如何,这是最适合我的方法。
创建一个名为“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;
这是发生了什么:
-
boundRectWithSize:options:context 得到一个矩形,它被限制为您传递给该方法的宽度。 NSStringDrawingUsesLineFragmentOrigin 选项告诉它期待多行字符串。
然后我们从该矩形中获取高度参数。
在 ios 7 中,此方法返回小数。我们需要一个圆形的图形。 ceilf 对此有所帮助。
我们为返回值添加了一个额外的单位。
这里是如何使用它
NSAttributedString *string = ...
CGFloat height = [string heightForWidth:320.0f];
您可以使用该高度进行布局计算。
【讨论】:
@ezinezync 你只是计算指定宽度内的高度,但是如何将高度限制为3行??? @0oneo 为此,您必须限制标签本身的numberOfLines
。我现在想不出另一种方法来做到这一点。
这不是在回答问题,主要问题是numberOfLines
这真的很难,因为 NSAttributedString 可以包含各种内容(甚至图像)。对我来说,这似乎真的很难解决。【参考方案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
【讨论】:
【参考方案3】: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;
【讨论】:
以上是关于如何计算 NSAttributedString 的高度,给定宽度和行数?的主要内容,如果未能解决你的问题,请参考以下文章