计算高度约束的NSAttributedString的高度

时间:2015-10-02 18:26:51

标签: ios nsattributedstring

方法[NSAttributedString boundingRectWithSize:options:context]允许定义绘制字符串的整个内容所需的高度。 我希望对高度有约束,并找到精确高度小于或等于给定的高度值,并允许绘制相同数量的文本,如果标签的高度等于约束值,则适合该文本。

我如何尝试完成此任务?

类似的任务是通过行数设置高度约束。也就是说,需要找到具有给定宽度和给定最大行数的属性文本的高度。

提前感谢您的回答。

1 个答案:

答案 0 :(得分:0)

最简单的解决方案可能只是通过计算一行的高度然后将总高度除以单行高度来设置UILabel上的行数。它有点天真,但应该可以解决这个问题。

以下是我对该建议的实施:

// Whatever your initial string is, attributes and all
NSAttributedString *myAttributedString = [[NSAttributedString alloc] initWithString:@"My Really Long String" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:[UIFont systemFontSize]]}];

// The frame that you want the label to fit in and not clip text
CGRect maximumFrame = CGRectMake(0.0f, 0.0f, CGFLOAT_MAX, MY_MAXIMUM_HEIGHT);

// This takes the attributes and assumes an infinitely wide frame and gives you a height
CGRect myStringBoundingRect = [myAttributedString boundingRectWithSize:maximumFrame.size
                                                     options:NSStringDrawingTruncatesLastVisibleLine
                                                     context:nil];

NSInteger numberOfLines = 1;

// This assumes the text has no line breaks in it and the text is only one line
if (myStringBoundingRect.size.height > 1 && myStringBoundingRect.size.height < maximumFrame.size.height) {
    numberOfLines = (NSInteger)(maximumFrame.size.height / myStringBoundingRect.size.height);
} else { // remove all line breaks and find the height for only one line
    NSRange rangeOfLineBreak = [myAttributedString.string rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]];

    if (rangeOfLineBreak.location != NSNotFound) {
        NSAttributedString *mySubstring = [myAttributedString attributedSubstringFromRange:rangeOfLineBreak];
        myStringBoundingRect = [mySubstring boundingRectWithSize:maximumFrame.size
                                                         options:NSStringDrawingTruncatesLastVisibleLine
                                                         context:nil];

        if (myStringBoundingRect.size.height > 1 && myStringBoundingRect.size.height < maximumFrame.size.height) {
            numberOfLines = (NSInteger)(maximumFrame.size.height / myStringBoundingRect.size.height);
        }
    }
}


UILabel *myLabel = [[UILabel alloc] initWithFrame:maximumFrame];
myLabel.attributedText = myAttributedString;

// Set the number of lines to match the maximum number of lines that fit in your frame
myLabel.numberOfLines = numberOfLines;

// resize the label
[myLabel sizeToFit];