Search code examples
objective-cioscore-animationcalayerquartz-graphics

Ghosting in [CALayer drawInContext]


I'm drawing as scrollable graph using a custom extension of CALayer with a bunch of CGContextAddCurveToPoint calls in [ MyCustomCALayer drawInContext].

I'm not actually drawing the whole length of the graph, rather, I'm redrawing the contents of the layer every time a UIPanGestureRecognizer updates to reflect the new horizontal offset. This way, I only draw the visible portion of the graph, and the layer's bounds only extend to the size of the screen.

[ MyCustomCALayer setNeedsDisplay ] gets called when graph data changes or the pan offset changes, which then causes [ MyCustomCALayer drawInContext] to be invoked.

However, I'm getting this weird ghosting whenever I redraw my layer during panning. A bit of searching around suggests it might be an implicit animation invoked by redrawing the layer's content, but I can't find a definitive answer.

Here's what the graph looks like at rest: At rest

And here it is during panning, with the ghosting redraw: During panning

Certainly, when I do draw the whole graph and adjust the layer's position property to pan it's not ghosting, but having a big long bitmap in memory seems like a Bad Thing.

Has anyone seen this kind of ghosting before? If it is (as I suspect) an implicit animation, how can I disable said animation?


Solution

  • It will probably be an implicit animation. Redraws (changes in contents) are animated like everything else in Core Animation.

    There are a number of ways to prevent this, if you're subclassing CALayer to do the drawing the best is to override -[CALayer actionForKey:], returning nil for change in contents:

    - (id<CAAction>)actionForKey:(NSString *)key 
    {
        if ([key isEqualToString: @"contents"]) 
        {
            return nil;
        }
    
        return [super actionForKey: key];
    }