Search code examples
ioscore-animationuiviewanimationtransition

Animation ends with error in custom interactive transitioning animation?


I am setting up a custom transitioning animation. Everything works fine except the error at the end of the animation:

enter image description here

As you see, after the interactive animation, the animation just excutes again.

This is the method i use to handle the the interactive gesture in the class the conforms to UIPercentDrivenInteractiveTransition and UIViewControllerAnimatedTransitioning:

func handlePan(recognizer: UIPanGestureRecognizer) {
    let maxMov:CGFloat = -300
    let translation = recognizer.translationInView(recognizer.view!.superview!)
    if(translation.y < 0){
        let value = (translation.y < maxMov) ? maxMov : translation.y
        let progress = value / maxMov
        switch recognizer.state {
        case .Changed:
            updateInteractiveTransition(progress)

        case .Cancelled, .Ended:                
            if progress < 0.5 {
                self.cancelInteractiveTransition()

            } else {
                self.finishInteractiveTransition()
            }
        default:
            break
        }
    }
}

Solution

  • Custom transitioning animation is based on CAAnimation whose timing is controlled by CAMediaTiming. In the handlePan method, you should reset the currentTiming of the container view in the transitioning.

    Firstly, define a stored context which will be later assigned in the animateTransitionmethod.

    var storedContext: UIViewControllerContextTransitioning?
    

    then get it in :

        func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        storedContext = transitionContext
        ....}
    

    Then in your handlePan:

            case .Cancelled, .Ended:
                let transitionLayer = storedContext!.containerView().layer
                transitionLayer.beginTime = CACurrentMediaTime()
            ....
    

    This ensures the containerLayer's begin time equals to the time you cancel or end the gesture! Without this process, the duplicated animation would occurs.