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:
setNeedsDisplay
method on each CALayer in the layer tree?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.
link to documentation
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With