使用NSLayoutManager计算文本大小

时间:2014-08-28 10:33:08

标签: ios core-text nslayoutmanager nstextcontainer

我正在处理一个使用TextKit框架在列中排版文本的视图,如下所示: Column Text Layout

我使用UIView的边界插入边界(黑色矩形)来计算10 CGRects然后我将其转换为NSTextContainers(红色矩形)。在drawRect:中,我将这些传递给NSLayoutManager哪些排版并为我绘制字形。

我的问题是:如何计算所需的列数?我可以绘制一定数量的列,但文本长度不同,我需要以编程方式调整列数。

我发现方法[NSLayoutManager glyphRangeForTextContainer:]在文本容器为空时返回长度为0的范围。因此,我可以循环创建文本容器并使用此方法来确定是否需要更多容器。然而,这种方法被认为是低效的,因为它触发了布局计算,并且我很高兴在循环中运行它可能数百次。

必须有更好的方法!

谢谢你的回答,皮特。

1 个答案:

答案 0 :(得分:3)

好吧,在深入了解TextKit框架之后,我终于找到了答案。

我的代码在这样的循环中工作:

while ([self needsMoreColumns]) {
    [self addColumn];
}

...

- (BOOL)needsMoreColumns {
    // Always create at least one column
    if (self.layoutManager.textContainers.count == 0)
        return YES;

    // Find out the glyph range of the last column
    NSRange range = [self.layoutManager glyphRangeForTextContainer:[self.layoutManager.textContainers lastObject]];
    NSUInteger glyphs = [self.layoutManager numberOfGlyphs];

    // Compare it with the number of glyphs
    return range.location + range.length < glyphs;
}

我没有包含方法[self addColumn],因为它不是一个明智的选择。它只是使用我的布局几何和最后一列的位置(如果有的话)来计算下一列的CGRect。然后,它创建具有相应大小的NSTextContainer,并将矩形的origin属性存储在专用数组中以用于绘图目的。

我还发现了方法[NSLayoutManager firstUnlaidCharacterIndex][NSLayoutManager firstUnlaidGlyphIndex],但它们似乎没有按预期工作。在仅在一列中布置三列文​​本后,它们返回整个字符串的长度,而不是第一个字符的位置,它不适合第一列。这就是为什么我宁愿使用基于范围的方法。

所有人都是安全的! 皮特。