0

我想找出一个字符串在设置为矩形内的字体时会有多少行。有没有办法做到这一点?

我有这段代码,但我试图让它处理得更快一点,因为它在滚动视图中被大量使用:

CGSize maximumSize = CGSizeMake(MESSAGE_FRAME.size.width - 16, 1000000);

    CGSize expectedSize = [message sizeWithFont:[UIFont fontWithName:@"Crimson" size:15]
                              constrainedToSize:maximumSize
                                  lineBreakMode:UILineBreakModeWordWrap];

return expectedSize.height;

我知道这会返回行高:

NSLog(@"%f", [[UIFont fontWithName:@"Crimson" size:15] lineHeight]);

因此,如果我可以将其乘以另一个值,它可能会更快。

4

3 回答 3

3

我想不出另一种选择,而且我怀疑是否会有一种效率更高的方法(毕竟,有什么魔法可以达到行数并避免自动换行计算?)。

无论如何,与其缩短计算周期而不是伤害我们的大脑,考虑是否需要在视图滚动时一遍又一遍地完成。我的猜测是否定的。

我认为加快速度的方法是进行传统的大小计算并缓存结果。

于 2012-05-17T15:16:32.893 回答
2

我不知道有什么不同的方法,但我有一个小建议,我在表格视图中的类似案例中做了。如果您的数据存储在某处(在我的情况下,我从网络接收文本并将其存储在数据库中),我仅在第一次收到文本时使用这种方式计算大小,然后存储此答案。加载数据时,我将大小放入数组中,以便快速检索值。

只是一个建议,希望对你有帮助。

于 2012-05-17T15:17:31.017 回答
2

对于iOS7及以上,官方认可的方式是使用TextKit:

func numberOfLinesForString(string: String, size: CGSize, font: UIFont) -> Int {
    let textStorage = NSTextStorage(string: string, attributes: [NSFontAttributeName: font])

    let textContainer = NSTextContainer(size: size)
    textContainer.lineBreakMode = .ByWordWrapping
    textContainer.maximumNumberOfLines = 0
    textContainer.lineFragmentPadding = 0

    let layoutManager = NSLayoutManager()
    layoutManager.textStorage = textStorage
    layoutManager.addTextContainer(textContainer)

    var numberOfLines = 0
    var index = 0
    var lineRange : NSRange = NSMakeRange(0, 0)
    for (; index < layoutManager.numberOfGlyphs; numberOfLines++) {
        layoutManager.lineFragmentRectForGlyphAtIndex(index, effectiveRange: &lineRange)
        index = NSMaxRange(lineRange)
    }

    return numberOfLines
}
于 2015-05-04T22:06:58.083 回答