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];
}
它非常简单,只需检查新高度是否大于滚动视图的内容大小,并使用新高度设置视图框架
这在一定程度上是可行的。当视图调整大小时,它会适当调整视图框架的大小,以封装内容的整个高度,从而显示滚动条。问题是:在滚动条可见的情况下调整视图大小时,栅格层的子层会抖动。以下是一段视频,显示了问题:
如您所见,当滚动条不可见时(换句话说,当内容的高度在滚动视图的范围内时),没有问题。我可以确认这不是布局管理器和处理单列的问题,因为我在没有滚动视图的情况下测试了相同的东西,并且没有任何抖动
非常感谢您的建议。通过翻转图层和视图的坐标系(原点位于左上角)解决了此问题。您能提供一个实际操作的示例吗?