Cocoa 将NSScrollView与CALayer一起使用

Cocoa 将NSScrollView与CALayer一起使用,cocoa,core-animation,calayer,nsview,nsscrollview,Cocoa,Core Animation,Calayer,Nsview,Nsscrollview,我正在尝试创建网格样式视图(类似于NSCollectionView),除了使用核心动画。我已经完成了很多,剩下要做的最后一件主要的事情就是实现滚动 到目前为止,我的设置是,我有一个NSView子类(以层为背景),在初始化时,它创建并添加网格层作为主视图层的子层。我已经为网格层创建了一个自定义的CALayoutManager,它以类似网格的形式排列其子视图。正如预期的那样,当我向网格层添加子层时,将调用布局管理器并自动定位层。到目前为止,一切都正常运转 当我尝试使用NSScrollView作为自定

我正在尝试创建网格样式视图(类似于
NSCollectionView
),除了使用核心动画。我已经完成了很多,剩下要做的最后一件主要的事情就是实现滚动

到目前为止,我的设置是,我有一个
NSView
子类(以层为背景),在初始化时,它创建并添加网格层作为主视图层的子层。我已经为网格层创建了一个自定义的
CALayoutManager
,它以类似网格的形式排列其子视图。正如预期的那样,当我向网格层添加子层时,将调用布局管理器并自动定位层。到目前为止,一切都正常运转

当我尝试使用
NSScrollView
作为自定义视图的父视图来实现滚动时,就会出现问题。我的设置如下:我在Interface Builder中将自定义视图创建为
NSScrollView
的子视图。然后,在布局管理器类中,我添加了一个
delegate
属性,在初始化期间,我的视图子类将自己设置为布局管理器的委托。在布局管理器的
layoutSublayersForLayer:
方法的末尾,我使用委托方法
layoutManager:contentHeightChanged:
调用其委托。下面是我的
NSView
子类中该方法的实现:

- (void)layoutManager:(MyLayoutManager*)manager contentHeightChanged:(CGFloat)height;
{
    CGFloat newHeight = [[self enclosingScrollView] contentSize].height;
    if (height > newHeight) {
        newHeight = height;
    }
    NSRect newFrame = [self frame];
    newFrame.size.height = newHeight;
    [self setFrame:newFrame];
}
它非常简单,只需检查新高度是否大于滚动视图的内容大小,并使用新高度设置视图框架

这在一定程度上是可行的。当视图调整大小时,它会适当调整视图框架的大小,以封装内容的整个高度,从而显示滚动条。问题是:在滚动条可见的情况下调整视图大小时,栅格层的子层会抖动。以下是一段视频,显示了问题:

如您所见,当滚动条不可见时(换句话说,当内容的高度在滚动视图的范围内时),没有问题。我可以确认这不是布局管理器和处理单列的问题,因为我在没有滚动视图的情况下测试了相同的东西,并且没有任何抖动


非常感谢您的建议。

通过翻转图层和视图的坐标系(原点位于左上角)解决了此问题。

您能提供一个实际操作的示例吗?