2

本のレイアウトに2 つあるNSTextfieldsのですが、前の「ページ」にすばやく戻る方法がわかりません。本のサイズ、フォント サイズ、行サイズはすべて変更されるため、前のページのテキストの文字列はその場で計算する必要があります。写真:

例

NSTextfields にはそれぞれ 1 つNSTextContainerの があり、 と を共有しNSLayoutManagerますNSTextStorage

先に進むのは簡単です。表示されているテキストの文字範囲を取得し、次の文字から始まる部分文字列を作成します。

私の戻る方法はクラッジです。一度に表示できる最大文字数を計算します。次に、その長さの文字列を作成し、最後の文字を本の右下隅に配置します。次に、ループします。最初から文字を削除し、必要な文字が右下に表示されるまで、毎回何が表示されるかを確認します。これは非常に遅いです。

私が達成したいことを行うためのより速い方法を誰かが提案できますか? を使用することを考えていましたが、このレイアウト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;
}
4

1 に答える 1

0

これがあなたが探している答えかどうかはわかりませんが、もしそれが私だったら、表示された以前のすべてのページについて、これらの文字範囲の束を「キャッシュ」するだけでしょう。ページ数の多い本の場合は、それらすべてを保管するのに問題はないでしょう。もちろん、ユーザーがテキストのサイズを変更するときなどに、まだぎこちないコードを使用する必要があります。(それか、適切な開始点から再計算することもできます...十分に速い場合は本の冒頭、または章の冒頭などを言います。次に、を含むページ(範囲)を見つけるだけですすでに表示されているテキストと前のテキストを表示します。)

于 2012-05-22T18:30:19.010 に答える