objective-c - 书籍布局 NSTextFields——返回页面?

标签 objective-c cocoa nstextview nsscrollview nstextstorage

我的书籍布局中有两个 NSTextfields,但我无法找到返回上一个“页面”的快速方法。书籍大小、字体大小、行大小都会发生变化,因此必须即时计算上一页的文本字符串。图片:

Example

每个 NSTextfields 都有一个 NSTextContainer,并且它们共享一个 NSLayoutManagerNSTextStorage

接下来很简单:我获取可见文本的字符范围,然后从下一个字符开始创建一个子字符串。

我的返回方法是一个拼凑。我计算出一次可以看到的最大字符数。然后,我制作一个达到该长度的字符串,最后一个字符是我想要在书的右下角的字符。然后我循环:从头开始删除字符,每次检查可见的内容,直到我想要的字符位于右下角。这非常非常慢。

任何人都可以建议一种更快的方法来实现我想要实现的目标吗?我想过使用 scrollRangeToVisible,但我不知道如何为此布局设置 NSScrollView

有人可以帮忙吗?

文本容器的设置如下:

-(void)setupTextViews {

articleString = [[NSAttributedString alloc] init];
articleStringPortion = [[NSAttributedString alloc] init];

bookTextStorage = [[NSTextStorage alloc] init];
bookLayoutManager = [[NSLayoutManager alloc] init];
[[self bookTextStorage] addLayoutManager:bookLayoutManager];

leftColumnRect = NSZeroRect;
rightColumnRect = NSZeroRect;

NSDivideRect(bookRect, &leftColumnRect, &rightColumnRect, NSWidth(bookRect) / 2, NSMinXEdge);

// First column
{
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:leftColumnRect.size];
    leftColumnTextView = [[CRMouseOverTextView alloc] initWithFrame:leftColumnRect textContainer:textContainer];
    [leftColumnTextView setDrawsBackground:NO];
    [leftColumnTextView setEditable:NO];
    [leftColumnTextView setup];

    [bookView addSubview:leftColumnTextView];

    [bookLayoutManager addTextContainer:textContainer];

    [textContainer release];
    [leftColumnTextView release];
}


// Second column
{
    NSTextContainer *textContainer = [[NSTextContainer alloc] initWithContainerSize:rightColumnRect.size];
    rightColumnTextView = [[CRMouseOverTextView alloc] initWithFrame:rightColumnRect textContainer:textContainer];
    [rightColumnTextView setDrawsBackground:NO];
    [rightColumnTextView setEditable:NO];
    [rightColumnTextView setup];

    [bookView addSubview:rightColumnTextView];

    [bookLayoutManager addTextContainer:textContainer];

    [textContainer release];
    [rightColumnTextView release];
}

}

发布我糟糕的后退代码是没有意义的,但我正在使用我发现的这种方法来找出每次可见的内容:

-(NSRange)getViewableRange:(NSTextView *)tv {
NSLayoutManager *lm = [tv layoutManager];
NSRect visRect = [tv visibleRect];

NSPoint tco = [tv textContainerOrigin];
visRect.origin.x -= tco.x;
visRect.origin.y -= tco.y;

NSRange glyphRange = [lm glyphRangeForBoundingRect:visRect inTextContainer:[tv textContainer]];
NSRange charRange = [lm characterRangeForGlyphRange:glyphRange actualGlyphRange:nil];

return charRange;
}

最佳答案

我不确定这就是您正在寻找的答案,但如果是我,我可能会为之前查看过的所有页面“缓存”一堆这些字符范围。对于一本有很多页的书来说,将它们全部存储起来可能不会有任何问题。当然,当用户调整文本大小或其他任何事情时,您仍然必须使用笨拙的代码。 (要么,或者你可以从一些合适的起点重新计算......如果足够快,就说书的开头,或者一章的开头或其他东西。然后你只需找到包含以下内容的页面(范围)已经显示的文本并显示前一个文本。)

关于objective-c - 书籍布局 NSTextFields——返回页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10700408/

相关文章:

ios - 具有自动布局和 UITableAutomaticDimension 的动态高度表单元格(动态 UILabel + 几个 UIImageViews)

macos - 如何在 OSX 上注册文档 MIME 类型,以便它出现在浏览器 navigator.MIMETypes 数组中

cocoa - 如何清除 NSTextView 选择而不使其成为第一响应者?

macos - 如何在 NSTextView 中禁用这些键盘快捷键?

objective-c - NSTextField 事件和辞职第一响应者

objective-c - 真的需要在程序退出时释放对象吗?

带有远程服务器的 iOS 应用程序 - 我不需要数据保留在应用程序上,我还应该使用 CoreData 吗?

objective-c - 试图将 RowAtIndexPath 移动到另一个部分,iOS

macos - 我可以在我的 macOS 应用程序中嵌入第 3 方命令行实用程序并将其提交到 Mac App Store 吗?

macOS - [NSValue valueWithCGAffineTransform :]