我在书籍布局中有两个NSTextfields
,我无法找到回到上一个“页面”的快捷方式。书本大小,字体大小,行大小都会发生变化,因此必须动态计算上一页的文本字符串。图片:
NSTextfields每个都有一个NSTextContainer
,他们共享NSLayoutManager
和NSTextStorage
。
前进很简单:我获取可见文本的字符范围,然后从下一个字符开始创建一个子字符串。
我的回归方法是一个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;
}
答案 0 :(得分:0)
我不确定这是你正在寻找的答案,但如果是我,我可能只是“缓存”一堆那些字符范围,对于以前查看过的所有页面。对于包含大量页面的书,你可能甚至都没有任何问题。当然,当用户重新调整文本大小时,你还是必须使用你的kludgy代码。 (要么那么,或者你可以从一些合适的起点重新计算...如果它足够快,或者章节的开头或者其他东西,请说出书的开头。然后你只需要找到包含该书的页面(范围)已经显示的文本并显示上一个文本。)