书籍布局NSTextFields - 返回页面?

时间:2012-05-22 10:40:43

标签: objective-c cocoa nstextview nsscrollview nstextstorage

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

Example

NSTextfields每个都有一个NSTextContainer,他们共享NSLayoutManagerNSTextStorage

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

我的回归方法是一个kludge。我找出了一次可见的最大字符数。然后我创建一个字符串到那个长度,最后一个字符是我想要的那个在书的右下角。然后循环:从开头删除字符,每次检查可见的内容,直到我想要的字符在右下角。这非常非常缓慢。

任何人都可以建议更快的方式来实现我想要实现的目标吗?我曾想过使用 scrollRangeToVisible ,但我无法弄清楚如何为此布局设置NSScrollView

有人可以帮忙吗?

Textcontainers设置如下:

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

1 个答案:

答案 0 :(得分:0)

我不确定这是你正在寻找的答案,但如果是我,我可能只是“缓存”一堆那些字符范围,对于以前查看过的所有页面。对于包含大量页面的书,你可能甚至都没有任何问题。当然,当用户重新调整文本大小时,你还是必须使用你的kludgy代码。 (要么那么,或者你可以从一些合适的起点重新计算...如果它足够快,或者章节的开头或者其他东西,请说出书的开头。然后你只需要找到包含该书的页面(范围)已经显示的文本并显示上一个文本。)