我正在尝试创建一个自定义 NSView
来托管 CALayer
层次结构以执行高效显示。此 NSView
然后嵌入到 NSTableCellView
中,该 View 由基于 View 的 NSOutlineView
显示。
问题是,每当我展开或折叠一个项目时,所有行都会被移动,但图层的内容仍显示在更改轮廓之前的位置。
滚动 NSOutlineView
似乎刷新了图层,此时它们与它们的行重新同步。
我已经使用 Instruments 调试了这种行为,看起来滚动会引发一个布局操作,该操作使用 setPosition:
调用更新图层,该调用应该在展开或折叠项目时发生。
这里是托管 NSView
子类的简单层的一些示例代码。
@interface TestView : NSView
@end
@implementation TestView
- (instancetype)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
CAShapeLayer* layer = [CAShapeLayer layer];
layer.bounds = self.bounds;
layer.position = CGPointMake(NSMidX(self.bounds), NSMidY(self.bounds));
layer.path = [NSBezierPath bezierPathWithOvalInRect:self.bounds].CGPath;
layer.fillColor = [NSColor redColor].CGColor;
layer.delegate = self;
self.layer = layer;
self.wantsLayer = YES;
return self;
}
@end
我已经针对这个问题尝试了很多潜在的解决方案,但我找不到任何有趣的方法来调用 NSView
实例,这些方法可以被覆盖以调用 [self.layer setNeedsDisplay]
或 [self.layer setNeedsLayout]
。我还在 CALayer
本身上尝试了各种 setter ,例如:
layer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
layer.needsDisplayOnBoundsChange = YES;
self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
谁能帮我弄清楚如何让这个图层在 NSOutlineView
中正确显示?
最佳答案
我终于回答了我的问题。问题不在于我的 TestView 的实现方式。我只是错过了在应用程序中启用 CoreAnimation 支持的步骤之一。相关引用在核心动画编程指南中。
基本上,在 iOS Core Animation 和 layer-backing 中总是默认启用。在 OS X 上,它必须以这种方式启用:
- 链接到 QuartzCore 框架
- 通过执行以下操作之一为一个或多个 NSView 对象启用图层支持
- 在您的 nib 文件中,使用 View 效果检查器为您的 View 启用图层支持。检查器显示所选 View 及其 subview 的复选框。建议您尽可能在窗口的内容 View 中启用图层支持
- 对于您以编程方式创建的 View ,调用 View 的 setWantsLayer: 方法并传递 YES 值以指示 View 应使用图层。
一旦我在任何 NSOutlineView 的父级上启用层支持,各种故障就解决了。
关于objective-c - 在 NSOutlineView 中托管 NSView 的图层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29109226/