4

これはとても些細な質問のように思えますが、しばらくの間私を悩ませてきました。

スクロールビューを含むウィンドウがあります。通常、スクロールビューにはクリップビューよりも垂直方向に大きいdocumentViewがあるため、垂直方向のスクローラーを使用して、スクロールビュー内のすべてのコンテンツを表示できます。

ウィンドウのサイズを変更すると、スクロールビューのdocumentViewのコンテンツのサイズが再計算されます(スクロールビューが薄くなる可能性があるため、documentViewの高さを大きくする必要がある場合があります)。ただし、副作用として、ウィンドウのサイズを変更すると、documentViewは、表示されている下端をクリップビューの下端と同じ高さに保ちます(つまり、テキストの最後の行が常に表示されるようにします)。これは奇妙な効果です。通常、ウィンドウはドキュメントビューの表示されている上端をクリップビューの上端と同じ高さに保ちます(つまり、ドキュメントビューのテキストの最上行は上部に固定されたままになります)。

したがって、この問題を修正するための最初の考えは、windowDidResize:またはwindowWillResize:toSize:通知を実装し、古いウィンドウフレームの高さと新しい高さの差に注意してから、スクロールビューをスクロールして維持することでした。スクロールビューの一番上の行が一番上に固定されています。

ただし、何らかの理由で、これは機能しないようです。ほぼ機能しますが、一部のサイズ変更デルタは1ピクセルずれているように見えます。ウィンドウのサイズを十分に速く変更すると、最大10ピクセルずれることがあります。したがって、その効果は、スクロールビューの一番上の行がほぼ一番上に固定されているということですが、完全ではなく、気が散ります。

これを行うためのより良い方法はありますか?関連するコードは次のとおりです。

- (void)windowDidResize:(NSNotification *)notification;
{
    if ([notification object] == mainWindow) {
        CGFloat currentWindowHeight = [mainWindow frame].size.height;

        // previousWindowHeight is an ivar
        NSNumber *heightDeltaNum = [NSNumber numberWithFloat:(currentWindowHeight - previousWindowHeight)];
        previousWindowHeight = currentWindowHeight;
        [[NSNotificationCenter defaultCenter] postNotificationName:@"AFSnapScrollView" object:heightDeltaNum];
    }
}

- (void)snapScrollViewNotification:(NSNotification *)theNotification;
{
    [self snapScrollView];

    NSNumber *heightDeltaNum = [theNotification object];

    CGFloat newY = [[tagScrollView documentView] visibleRect].origin.y - [heightDeltaNum floatValue];
    NSPoint pointToScroll = NSMakePoint(0,newY);
    [[tagScrollView documentView] scrollPoint:pointToScroll];
}

- (void)snapScrollView;
{

    [...]

    // adjust the view frame
    [[tagScrollView documentView] setFrame:NSMakeRect(0, 0, existingDocumentFrame.size.width, newDocumentViewHeight)];

    [...]

}
4

3 に答える 3

10

ドキュメントビューは-(BOOL)isFlippedメソッドをオーバーライドし、YESを返す必要があります。

于 2010-07-28T10:17:34.843 に答える
1

座標を反転した後、clipviewを回してもdocumentViewを変更する必要はありません。

@interface FlippedClipView : NSClipView 
@end

@implementation FlippedClipView
- (BOOL)isFlipped
{
    return YES;
}
@end
于 2014-01-08T13:13:56.750 に答える
0

scrollViewにcontentInsetsを追加した場合、サイズ変更の最後のオフセット設定が、下のインセットのサイズだけずれていることがわかりました。とてもイライラします。

カスタムNSScrollViewで次のように修正しました。

    var lastOffset = NSPoint.zero

    override func viewWillStartLiveResize() {
        lastOffset = documentVisibleRect.origin
    }

    override func viewDidEndLiveResize() {
        documentView?.scroll(lastOffset)
    }

scrollViewのサイズが変更されたときにサイズが変更されるdocumentViewがある場合は、それらを元に戻すときにオフセット計算を行う必要があります。動きをスムーズに保つために、ライブサイズ変更呼び出しの間にある各layout()呼び出しの後にオフセットを設定する必要があります。

于 2019-02-01T14:21:20.590 に答える