我在阅读this article from objc.io后,使用NSAttributedString's
boundingRectWithSize: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
,为它提供与tableview单元格中UILabel
相同的属性(numberOfLines
等),然后使用sizeThatFits:
来计算尺寸。它确实是一个黑客攻击 - 但它足以解决我的问题。不过我希望它更优雅!
答案 0 :(得分:3)
在尝试计算UITextView的属性文本大小时,我遇到了同样的效果。我遇到了this answer to another question。
诀窍是使用NSLayoutManager's usedRectForTextContainer:
。什么是整洁的是这个方法不需要与UITextView一起使用。这意味着您可以将它从mainThread,key用于预先计算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。我对这整个编程工作都很陌生,所以如果我的代码可以优化,请告诉我。
答案 1 :(得分:1)
我想,你可能不会设置preferredMaxLayoutWidth
。
此属性将约束设置为视图的最大宽度。