在调整窗口大小时固定NSScrollView的文档视图

时间:2010-07-28 07:37:43

标签: cocoa nsscrollview

这似乎是一个微不足道的问题,但它让我感到烦恼了一段时间。

我有一个包含滚动视图的窗口。通常,滚动视图的文档视图垂直大于剪辑视图,因此您可以使用垂直滚动条查看滚动视图中的所有内容。

当我调整窗口大小时,我会重新计算滚动视图的documentView中内容的大小(因为滚动视图可以变得更薄,这可能使documentView必须增加高度)。然而,副作用是,在调整窗口大小时,documentView会使底部可见边缘与剪辑视图的下边缘齐平(也就是说,它确保最后一行文本始终可见)。这是一种奇怪的效果,因为通常情况下,窗口使文档视图的顶部可见边缘与剪辑视图的顶部边缘齐平(即,文档视图中最顶部的文本行保持固定在顶部)。

所以,我最初想要解决这个问题只是为了实现一个windowDidResize:或windowWillResize:toSize:notification,注意旧窗口框架高度和新高度之间的差值,然后简单地滚动滚动视图为了保持滚动视图的顶行固定在顶部。

然而,出于某种原因,这似乎不起作用。它几乎有效,但是一些调整大小的增量似乎是一个像素关闭,如果你足够快地调整窗口大小,它有时会关闭~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)];

    [...]

}

3 个答案:

答案 0 :(得分:10)

您的文档视图需要覆盖 - (BOOL)isFlipped方法并返回YES。

答案 1 :(得分:1)

翻转clipview后,不需要修改documentView。

@interface FlippedClipView : NSClipView 
@end

@implementation FlippedClipView
- (BOOL)isFlipped
{
    return YES;
}
@end

答案 2 :(得分:0)

我发现,如果将contentInsets添加到我的scrollView中,则调整大小末尾的偏移量设置会因底部插入物的大小而偏离。非常沮丧。

我使用以下自定义NSScrollView修复了该问题。

    var lastOffset = NSPoint.zero

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

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

如果具有当scrollView调整大小时调整大小的documentView,则需要在将其重新设置时进行偏移量计算。您需要在每次live resize调用之间的每个layout()调用之后设置偏移量,以保持移动顺畅。