Cocoa 在层承载视图上调用setNeedsDisplay:YES不会重新绘制视图
我在自定义Cocoa 在层承载视图上调用setNeedsDisplay:YES不会重新绘制视图,cocoa,core-animation,Cocoa,Core Animation,我在自定义NSView子类中设置了一个层宿主视图,如下所示: [self setLayer:rootLayer]; [self setWantsLayer:YES]; 在调用每个子层上的setNeedsDisplay后,我将所有子层添加到层树中。每个层的内容都由我的层代理的drawLayer:inContext方法提供 我的问题是: 初始化视图后,视图将正确绘制。但是,当模型发生变化时,我调用[myCustomView setNeedsDisplay:YES]从我的视图控制器中,不调用绘图层:
NSView
子类中设置了一个层宿主视图,如下所示:
[self setLayer:rootLayer];
[self setWantsLayer:YES];
在调用每个子层上的setNeedsDisplay
后,我将所有子层添加到层树中。每个层的内容都由我的层代理的drawLayer:inContext
方法提供
我的问题是:
初始化视图后,视图将正确绘制。但是,当模型发生变化时,我调用[myCustomView setNeedsDisplay:YES]代码>从我的视图控制器中,不调用绘图层:inContext
我现在不知道如何更新视图:
[self setLayer:rootLayer];
[self setWantsLayer:YES];
self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
- 我是否必须在层树中的每个层上调用
setNeedsDisplay
方法
- 在图层宿主视图本身上调用
setNeedsDisplay:YES
是否应该触发整个图层树的重画
谢谢你的帮助
编辑
我在NSView类参考中找到了一些内容
层备份视图是由核心动画层备份的视图。视图完成的任何图形都会缓存在背衬层中。您只需调用值为YES的setWantsLayer:即可配置层备份视图。view类将自动为您创建背景层,您可以使用view类的绘图机制。使用图层备份视图时,决不应直接与图层交互
层宿主视图是包含要直接操纵的核心动画层的视图。通过实例化核心动画层类的实例并使用视图的setLayer:方法设置该层,可以创建承载视图的层。执行此操作后,然后使用值YES调用setWantsLayer:。使用图层主体视图时,不应依赖该视图进行绘图,也不应向图层主体视图添加子视图
在我的例子中,我有一个层托管视图。那么这真的意味着我必须手动触发重画吗?我是否应该在自定义NSView中实现一个伪drawRect方法,以便在更改的Calayer上调用相应的setNeedsDisplay?在进一步研究Apple的kiosk样式菜单后,我发现如果您使用的是层宿主视图,您必须注意屏幕更新,这是由于您自己更改了模型所必需的。在NSView上调用setNeedsDisplay:YES
将不起任何作用
因此,如果必须更新视图,则必须编写一个类似reloadData的方法,并在其中对每个需要刷新的CALayer调用setNeedsDisplay
。我仍然不确定根层上对该方法的调用是否会传播到所有子层,但我不这么认为
我现在通过调用需要重新校准的各个Calayer上的setNeedsDisplay
解决了这个问题。它可以毫无问题地工作。还有一种常用的做法,即使用一个空的“drawrect”,一个la-(void)drawrect:(NSRect)dirtyRect{}
来帮助将内容强制到绘图中,我相信这是通过良好的ole视图实现的。needsDisplay=YES代码>
值得注意的是。。实际上发生的是——通过说出你的NSView*视图代码>是layer.delegate=视图代码>导致在[图层设置需要显示]时绘制图层代码>被称为。。。。via-(void)drawLayer:(CALayer*)层inContext:(CGContextRef)ctx{…}
同样的道理。。。当说layer.layoutManager=view
。。。[layer setNeedsLayout]的后续需求仅当实现了-(void)layoutSublayersOfLayer:(CALayer*)layer{..}
方法时,才会实现code>
这些重要的概念在苹果的文档中被掩盖了。。。而且它们对于使任何东西都能正常工作来说都是非常关键的。通过更改视图的重画策略,您可以自动委托设置需要显示:
。您必须将nsviewLayerContentsRedawOnSetNeedsDisplay
分配给属性LayerContentsRedawPolicy
(请参阅)。当您将setNeedsDisplay:
发送到视图时,这将触发图层的重绘:
[self setLayer:rootLayer];
[self setWantsLayer:YES];
self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawOnSetNeedsDisplay;
或使用Swift:
layer = rootLayer
wantsLayer = true
layerContentsRedrawPolicy = .onSetNeedsDisplay
您与示例代码的链接已断开,也许这是替换:您能解释一种对初学者更友好的方式吗?@carbor我知道这很混乱。但我所说的很简单。如果显示不正确,并且您的视图是图层的代理。。您需要实现drawLayer:inContext
,并且可能有一个空的drawRect:
并调用setNeedsDisplay
。如果有必要的话,读10遍,但是信息都在那里。如果我没记错的话,那就是