我可以使用CALayer加快视图渲染吗? [英] Can I use CALayer to speed up view rendering?

查看:98
本文介绍了我可以使用CALayer加快视图渲染吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个自定义NSView对象,它有一些内容经常更改,一些更改很少更改。因为它会发现,变化较少的部分需要最多的时间绘制。我想做的是在不同的层中渲染这两个部分,以便我可以单独更新一个或另一个,从而节省我的用户一个缓慢的用户界面。

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.

我怎么可能这样做?我还没有找到许多好的教程这种事情,没有人谈到在CALayer渲染NSBezierPaths。想法任何人?

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.

所有你需要做的是添加 CALayer 对于视图中的每个内容项目。要绘制图层,您应该将视图设置为每个图层的委托,然后实现 drawLayer:inContext:方法。

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 the drawLayer:inContext: method.

在该方法中,您只需绘制每个图层的内容:

In that method you just draw the content of each layer:

- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx
{
    if(layer == yourBackgroundLayer)
    {   
        //draw your background content in the context
        //you can either use Quartz drawing directly in the CGContextRef,
        //or if you want to use the Cocoa drawing objects you can do this:
        NSGraphicsContext* drawingContext = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:YES];
        NSGraphicsContext* previousContext = [NSGraphicsContext currentContext];
        [NSGraphicsContext setCurrentContext:drawingContext];
        [NSGraphicsContext saveGraphicsState];
        //draw some stuff with NSBezierPath etc
        [NSGraphicsContext restoreGraphicsState];
        [NSGraphicsContext setCurrentContext:previousContext];
    }
    else if (layer == someOtherLayer)
    {
        //draw other layer
    }
    //etc etc
}

当您要更新其中一个图层的内容时,只需调用 yourLayer setNeedsDisplay]

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.

请注意,默认情况下,当您更改图层内容时,Core Animation提供了一个很好的淡入淡出转换为新内容。但是,如果你自己处理图形,你可能不想要这样,所以为了防止默认的淡入淡出动画当图层内容改变时,你还必须实现 actionForLayer:forKey: 委托方法,并通过返回空操作来阻止动画:

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:

- (id<CAAction>)actionForLayer:(CALayer*)layer forKey:(NSString*)key 
{
    if(layer == someLayer)
    {
        //we don't want to animate new content in and out
        if([key isEqualToString:@"contents"])
        {
            return (id<CAAction>)[NSNull null];
        }
    }
    //the default action for everything else
    return nil;
}

这篇关于我可以使用CALayer加快视图渲染吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆