Pause transform animation and then fade out

I have a UIImage view that I'm rotating indefinitely vertically by performing a transform on the layer:


        var keyTransform = CATransform3DIdentity
        keyTransform.m34 = -0.001
        keyFrameAnimation = CAKeyframeAnimation(keyPath: "transform")
        if let kfAnimation = keyFrameAnimation {
            kfAnimation.values = [
                CATransform3DRotate(keyTransform, 0, 1, 0, 0),
                CATransform3DRotate(keyTransform, .pi / 2, 1, 0, 0),
                CATransform3DRotate(keyTransform, .pi, 1, 0, 0),
                CATransform3DRotate(keyTransform, 3/2 * .pi, 1, 0, 0),
                CATransform3DRotate(keyTransform, 2 * .pi, 1, 0, 0)
            ]
            kfAnimation.beginTime = CACurrentMediaTime()
            kfAnimation.duration = 8
            kfAnimation.repeatCount = .greatestFiniteMagnitude
            key.layer.zPosition = CGFloat(Float.greatestFiniteMagnitude)
            key.layer.add(kfAnimation, forKey: "transform")
        }



When a certain event happens (i.e. touch), I want to pause the animation and then fade out (alpha = 0) the layer.


            let pausedTime = key.layer.convertTime(CACurrentMediaTime(), from: nil)
            key.layer.speed = 0.0
            key.layer.timeOffset = pausedTime

            UIView.animate(withDuration: self.fadeOutDuration, delay: 0, options: [.curveLinear], animations: {
                self.key.alpha = 0
            }, completion: {(animationsCompleted) in

            })


My problem is that pausing the animation by setting the speed to zero also prevents any further animations (i.e. fading out) from happening.





If I remove the transform animation before fading out, then the image no longer pauses at the moment the event happens...rather, the animation resets to the beginning and then fades out...I don't want that behaviour.


key.layer.removeAnimation(forKey: "transform")


Any suggestions on how I can pause the transform animation and then fade it out?

Maybe I can extract a copy of exactly what the layer is rendering at the moment the event occurs, display it in a new sublayer over top of my existing layer, hide the original layer, and then fade out the new layer? I don't know how to implement that idea, though...maybe there's a better way?

Accepted Reply

Instead of pausing the animation, you instead want to get the current value of the transform animation, set it as the current transform, then remove your animation. The presentationLayer can be used to obtain the current rendered transform for this purpose.


layer.transform = layer.presentationLayer.transform
layer.removeAnimation(forKey: "transform")
// do the rest

Replies

Instead of pausing the animation, you instead want to get the current value of the transform animation, set it as the current transform, then remove your animation. The presentationLayer can be used to obtain the current rendered transform for this purpose.


layer.transform = layer.presentationLayer.transform
layer.removeAnimation(forKey: "transform")
// do the rest