I am making a custom NSView object that has some content that changes often, and some that changes much more infrequently. As it would turn out, the parts that change less often take the most time to draw. What I would like to do is render these two parts in different layers, so that I can update one or the other separately, thus sparing my user a sluggish user interface.
How might I go about doing this? I have not found many good tutorials on this sort of thing, and none that talk about rendering NSBezierPaths on a CALayer. Ideas anyone?
Your hunch is right, this is actually an excellent way to optimise drawing. I've done it myself where I had some large static backgrounds that I wanted to avoid redrawing when elements moved on top.
All you need to do is add
CALayer
objects for each of the content items in your view. To draw the layers, you should set your view as the delegate for each layer and then implement thedrawLayer:inContext:
method.In that method you just draw the content of each layer:
When you want to update the content of one of the layers, just call
[yourLayer setNeedsDisplay]
. This will then call the delegate method above to provide the updated content of the layer.Note that by default, when you change the layer content, Core Animation provides a nice fade transition for the new content. However, if you're handling the drawing yourself you probably don't want this, so in order to prevent the default fade in animation when the layer content changes, you also have to implement the
actionForLayer:forKey:
delegate method and prevent the animation by returning a null action: