在NSOutlineView中托管NSView的图层

Dal*_*him 15 macos cocoa objective-c calayer nsoutlineview

我正在尝试创建一个NSView托管CALayer层次结构的自定义来执行高效显示.这NSView随后被嵌入内NSTableCellView由一个基于视图的显示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
Run Code Online (Sandbox Code Playgroud)

我已经尝试了很多这个问题的潜在解决方案,但我找不到任何有趣的方法,NSView可以覆盖调用[self.layer setNeedsDisplay]或实例[self.layer setNeedsLayout].我也尝试了各种各样的setter,CALayer例如:

layer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
layer.needsDisplayOnBoundsChange = YES;
self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮我弄清楚如何在一个内部正确显示这一层NSOutlineView

Dal*_*him 5

我最后回答了我的问题.问题不在于我的TestView实现方式.我简单地错过了在应用程序中启用CoreAnimation支持的其中一个步骤.相关参考文献在"核心动画编程指南"中.

基本上,在iOS Core Animation中,默认情况下始终启用图层支持.在OS X上,必须以这种方式启用它:

  1. 链接QuartzCore框架
  2. 通过执行以下操作之一,为一个或多个NSView对象启用图层支持
    • 在nib文件中,使用View Effects检查器为视图启用图层支持.检查器显示所选视图及其子视图的复选框.建议您尽可能在窗口的内容视图中启用图层支持
    • 对于以编程方式创建的视图,请调用视图的setWantsLayer:方法并传递值YES以指示视图应使用图层.

一旦我在任何NSOutlineView的父母上启用了图层支持,就会解决各种故障.