3

我正在开发一个视图,它使用 TextKit 框架来排版这样的列中的文本: 列文本布局

我使用UIView带有边缘插图(黑色矩形)的边界来计算 10 CGRects,然后将其转换为NSTextContainers(红色矩形)。在drawRect:我将这些传递给NSLayoutManagerwhich 为我排版和绘制字形。

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

[NSLayoutManager glyphRangeForTextContainer:]当文本容器为空时,我找到了返回长度范围为 0 的方法。因此,我可以循环创建文本容器并使用此方法来确定是否需要更多容器。但是,据说这种方法效率低下,因为它会触发布局计算,而且我不乐意将它循环运行数百次。

一定有更好的方法!

谢谢你的回答,皮特。

4

1 回答 1

3

Well, after some digging through the TextKit framework I've finally found the answer.

My code works in a loop like this:

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;
}

I didn't include the method [self addColumn] as it's a no brainer. It simply uses the geometry of my layout and position of the last column (if any) to compute the CGRect of the next one. Then, it creates NSTextContainer with respective size and stores the origin property of the rectangle in a dedicated array for drawing purposes.

I've also discovered methods [NSLayoutManager firstUnlaidCharacterIndex] and [NSLayoutManager firstUnlaidGlyphIndex] but they don't seem to work as expected. After laying out three columns worth of text in only one column, they returned the length of the entire string and not the position of the first character which didn't fit into the first column. That's why I rather used the range-based approach.

That's all folks, be safe! Pete.

于 2014-08-29T09:22:34.300 回答