Search code examples
cocoa-touchcore-animationavfoundation

AVSynchronizedLayer sublayer animations that don't match the timing of movie


I'm using an AVSynchronizedLayer to animate a CALayer's position along a path. Since the timing of the layers is matched to the AVPlayerItem, the layers correctly track an item in the video as it's playing.

What I'd like to do is also have a separate opacity/rotation animation on the layer, but I want it's timing to be independent of the video. Is there any way to override this?


Solution

  • The only way to do this was to animate the opacity/rotation manually using a CADisplayLink and interpolating the values without using Core Animation.

    startTimestamp = CACurrentMediaTime();
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self
                                                             selector:@selector(animate:)]
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] 
                      forMode:NSDefaultRunLoopMode];
    
    ...
    
    - (void)animate:(CADisplayLink *)link {    
        float duration = 1.0;
        float dt = (link.timestamp - startTimestamp) / duration;
    
        // Done?
        if (dt > 1.0) {
            [link invalidate];
            return;
        }
    
        // Disable CoreAnimation implicit animations
        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        layer.opacity = dt;
        [CATransaction commit];
    }