在层主机视图上调用setNeedsDisplay:YES不会重绘视图 [英] Calling setNeedsDisplay:YES on layer-hosting view does not redraw the view
问题描述
我在自定义的 NSView
子类中设置了一个层主机视图:
[self setLayer:rootLayer];
[self setWantsLayer:YES];
我在调用 setNeedsDisplay >之后将所有子图层添加到图层树中。 code>每个子图层。每一层的内容都是由我的层的委托的
drawLayer:inContext
方法提供的。
这里是我的问题: / p>
初始化我的视图后,视图绘制正确。但是,当模型改变,我调用 [myCustomView setNeedsDisplay:YES];
从我的视图控制器 drawLayer:inContext
现在我很困惑如何更新视图:
- 我必须在图层树中的每个CALayer上调用
setNeedsDisplay
方法吗? - $ c> setNeedsDisplay:YES 在层托管视图本身触发整个图层树的重绘?
感谢您的帮助。
编辑
NSView类引用
基于layer的视图是一个由Core Animation层支持的视图。视图执行的任何绘图都在缓存在后台层中。您通过简单地调用setWantsLayer:值为YES来配置基于图层的视图。视图类将自动为您创建一个背景层,并使用视图类的绘图机制。使用分层视图时,您不应该直接与该图层进行交互。
图层托管视图是一个视图,包含您要直接操作的Core Animation图层。您可以通过实例化Core Animation图层类的实例并使用视图的setLayer:方法设置该层来创建层托管视图。在这样做后,然后调用setWantsLayer:值为YES。在使用图层托管视图时,您不应该依赖视图进行绘制,也不应该将图层添加到图层托管视图。
在我的例子中,我有一个层主机视图。这是否意味着我必须手动触发重绘?我应该在自定义NSView中实现一个伪drawRect方法来调用在更改的CALayers上的相应setNeedsDisplay?
在Apple的示例代码中kiosk样式菜单我发现,如果你使用一个层主机视图,你必须照顾到屏幕更新,这是必要的,由于模型更改自己。调用NSView上的 setNeedsDisplay:YES
将不会做任何事情。
更新一个视图,应该写一个像reloadData这样的方法,并且在每个需要刷新的CALayer上调用 setNeedsDisplay
。我仍然不确定如果在根层调用这个方法将传播通过所有的孩子层,但我不这么认为。
我解决了现在的问题在需要重新缓存的单个CALayers上调用 setNeedsDisplay
。它工作没有问题。
I have a layer-hosting view set up like this in a custom NSView
subclass:
[self setLayer:rootLayer];
[self setWantsLayer:YES];
I add all the sublayers to the layer tree after I called setNeedsDisplay
on each sublayer. Each layer's content is provided by a drawLayer:inContext
method of my layer's delegate.
Here is my problem:
After initializing my view the view gets draw correctly. However, when the model has changed and I call [myCustomView setNeedsDisplay:YES];
from my view controller the drawLayer:inContext
is not called.
I am confused now how to update the view:
- Do I have to call the
setNeedsDisplay
method on each CALayer in the layer tree? - Should not the call of
setNeedsDisplay:YES
on the layer-hosting view itself trigger the redraw of the whole layer tree?
Thanks for your help.
Edit
I have found something in the NSView Class reference
A layer-backed view is a view that is backed by a Core Animation layer. Any drawing done by the view is the cached in the backing layer. You configured a layer-backed view by simply invoking setWantsLayer: with a value of YES. The view class will automatically create the a backing layer for you, and you use the view class’s drawing mechanisms. When using layer-backed views you should never interact directly with the layer.
A layer-hosting view is a view that contains a Core Animation layer that you intend to manipulate directly. You create a layer-hosting view by instantiating an instance of a Core Animation layer class and setting that layer using the view’s setLayer: method. After doing so, you then invoke setWantsLayer: with a value of YES. When using a layer-hosting view you should not rely on the view for drawing, nor should you add subviews to the layer-hosting view.
In my case I have a layer-hosting view. So does that indeed mean that I have to trigger the redraw manually? Should I implement a pseudo drawRect method in the custom NSView to call the appropriate setNeedsDisplay on the CALayers that changed?
After further research in Apple's sample code of a kiosk-style menu I found out that if you are using a layer-hosting view, you have to take care of the screen updates which are neccessary due to model changes yourself. Calling setNeedsDisplay:YES
on the NSView will not do anything.
So what one has to do if one has to update a view one should write a method like reloadData and in it one should call setNeedsDisplay
on each CALayer that needs a refresh. I am still not sure if a call to this method on the root layer will propagate through all the children layers but I do not think so.
I solved the problem now by calling setNeedsDisplay
on the individual CALayers that needed recaching. It works without problems.
这篇关于在层主机视图上调用setNeedsDisplay:YES不会重绘视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!