在图层托管视图上调用setNeedsDisplay:YES不会重绘视图

Gor*_*tch 8 cocoa core-animation

我在自定义NSView子类中设置了这样的图层托管视图:

[self setLayer:rootLayer];
[self setWantsLayer:YES];
Run Code Online (Sandbox Code Playgroud)

在我调用setNeedsDisplay每个子图层后,我将所有子图层添加到图层树中.每个图层的内容都由drawLayer:inContext我图层的委托方法提供.

这是我的问题:

初始化视图后,视图会正确绘制.但是,当模型发生变化并且我[myCustomView setNeedsDisplay:YES];从视图控制器调用时,drawLayer:inContext不会调用它.

我现在很困惑如何更新视图:

  • 我是否必须setNeedsDisplay在图层树中的每个CALayer上调用该方法?
  • 不应该setNeedsDisplay:YES在图层托管视图本身的调用触发重绘整个图层树吗?

谢谢你的帮助.

编辑

我在NSView Class引用中找到了一些东西

图层支持的视图是由Core Animation图层支持的视图.视图完成的任何绘制都将缓存在背衬层中.您通过简单地调用setWantsLayer配置了一个图层支持的视图:值为YES.视图类将自动为您创建背衬层,并使用视图类的绘制机制.使用图层支持的视图时,不应直接与图层交互.

图层托管视图是包含您要直接操作的Core Animation图层的视图.您可以通过实例化Core Animation图层类的实例并使用视图的setLayer:方法设置该图层来创建图层托管视图.执行此操作后,您将调用setWantsLayer:值为YES.使用图层托管视图时,不应依赖视图进行绘制,也不应将子视图添加到图层托管视图.

链接到文档

在我的情况下,我有一个图层托管视图.那么这确实意味着我必须手动触发重绘吗?我应该在自定义NSView中实现一个伪drawRect方法来调用更改的CALayers上的相应setNeedsDisplay吗?

Gor*_*tch 10

在进一步研究Apple的自助服务亭式菜单示例代码后,我发现如果您使用的是图层托管视图,则必须自行处理由于模型更改而需要的屏幕更新.调用setNeedsDisplay:YESNSView将不会执行任何操作.

因此,如果必须更新视图,则必须执行的操作应该编写一个类似reloadData的方法,并且在其中应该调用setNeedsDisplay需要刷新的每个CALayer.我仍然不确定根层上对此方法的调用是否会传播到所有子层,但我不这么认为.

我现在通过调用setNeedsDisplay需要重新缓存的单个CALayers来解决问题.它没有问题.