我可以使用 CALayer 来加速视图渲染吗?
我正在制作一个自定义 NSView 对象,其中一些内容经常更改,而另一些内容则很少更改。事实证明,变化较少的部分需要花费最多的时间来绘制。我想做的是将这两个部分呈现在不同的层中,以便我可以分别更新其中一个或另一个,从而使我的用户免受缓慢的用户界面的困扰。
我该怎么做呢?我还没有找到很多关于此类事情的好的教程,也没有一个讨论在 CALayer 上渲染 NSBezierPaths。有人有想法吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的预感是正确的,这实际上是优化绘图的绝佳方法。我自己做过,我有一些大型静态背景,我想避免当元素移动到顶部时重新绘制。
您所需要做的就是为视图中的每个内容项添加 CALayer 对象。要绘制图层,您应该将视图设置为每个图层的委托,然后实现
drawLayer:inContext:
方法。在该方法中,您只需绘制每个图层的内容:
当您想要更新其中一个图层的内容时,只需调用
[yourLayer setNeedsDisplay]
。然后,这将调用上面的委托方法来提供图层的更新内容。请注意,默认情况下,当您更改图层内容时,核心动画会为新内容提供良好的淡入淡出过渡。但是,如果您自己处理绘图,您可能不希望这样做,因此为了防止图层内容更改时动画默认淡出,您还必须实现
actionForLayer:forKey:
委托方法并通过返回 null 操作来阻止动画: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: