Search code examples
iosswiftuinavigationcontrolleruiviewanimation

animateTransition not called on push


I have just notated that :

func animateTransition(transitionContext: UIViewControllerContextTransitioning)

Is not called id I push my UIViewController :

navigationController?.pushViewController(nextVC, animated: true)

Otherwise if I present my UIViewController:

navigationController?.presentViewController(nextVC, animated: true, completion: nil)

My animation works because animateTransition is called

EDIT:

it is used like that:

let transitionManager = TransitionManager()
nextVC.transitioningDelegate = transitionManager
navigationController?.pushViewController(nextVC, animated: true)

The full animation class is that:

class TransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate {
    private var presenting = true

    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

        let container = transitionContext.containerView()
        let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!
        let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!


        let offScreenRight = CGAffineTransformMakeTranslation(container!.frame.width, 0)
        let offScreenLeft = CGAffineTransformMakeTranslation(-container!.frame.width, 0)

        toView.transform = offScreenRight

        container!.addSubview(toView)
        container!.addSubview(fromView)


        let duration = self.transitionDuration(transitionContext)


        UIView.animateWithDuration(duration, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.8, options: [], animations: {
            fromView.transform = offScreenLeft
            toView.transform = CGAffineTransformIdentity

            }) { (finished) in
                transitionContext.completeTransition(true)
         }


    }

    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
        return 2
    }

    // MARK: UIViewControllerTransitioningDelegate protocol methods
     func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
         self.presenting = true
        return self
    }
     func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        self.presenting = false
        return self
    }
}

Solution

  • The problem is that you are saying:

    nextVC.transitioningDelegate = transitionManager
    

    That is how you configure a present custom transition. But it is not how you configure a push custom transition.

    To configure a push custom transition, give the navigation controller a delegate (not a transitioningDelegate) and, in the delegate, implement:

    func navigationController(_ navigationController: UINavigationController, 
        animationControllerFor operation: UINavigationControllerOperation, 
        from fromVC: UIViewController, 
        to toVC: UIViewController) -> 
        UIViewControllerAnimatedTransitioning? {