2

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

例子

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

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

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

谁能建议一种更快的方法来完成我想要实现的目标?我曾想过使用,但我不知道如何为此布局scrollRangeToVisible设置 a 。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;
}
4

1 回答 1

0

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

于 2012-05-22T18:30:19.010 回答