Navigation controller custom transition animation

ios push view controller custom animation
pushviewcontroller animation swift
uinavigationcontroller setviewcontrollers custom animation
navigation bar animation swift
ios view controller transition animation
uiviewcontroller transition animation objective-c
uinavigationcontroller push animation
present view controller with animation swift

I've been following some tutorials to create custom animation while transitioning from one view to another.

My test project using custom segue from here works fine, but someone told me it's not encouraged anymore to do custom animation within a custom segue, and I should use UIViewControllerAnimatedTransitioning.

I followed several tutorials that make use of this protocol, but all of them are about modal presentation (for example this tutorial).

What I'm trying to do is a push segue inside a navigation controller tree, but when I try to do the same thing with a show (push) segue it doesn't work anymore.

Please tell me the correct way to do custom transitioning animation from one view to another in a navigation controller.

And is there anyway I can use one method for all transitioning animations? It would be awkward if one day I want to do the same animation but end up having to duplicate the code twice to work on modal vs controller transitioning.

Simple, custom navigation transitions, Default transition animation overlaps a little bit the source and destination views, therefore, there is only one way to make our application navigate with some dignity and smoothness — that's right — it is custom animated transitioning and since we usually want to keep swipe to back gesture on view controllers we also The navigation controller delegate or the transitioning delegate requests for an optional interaction controller after requesting an animation controller. Let’s create the interaction controller. Create a new class and name it CustomInteractionController and make it a subclass of UIPercentDrivenInteractiveTransition .

You may wanna add the following code before addSubview

  toViewController.view.frame = [transitionContext finalFrameForViewController:toViewController];

From another question custom-transition-for-push-animation-with-navigationcontroller-on-ios-9

From Apple's Documentation for finalFrameForViewController:

Returns the ending frame rectangle for the specified view controller’s view.

The rectangle returned by this method represents the size of the corresponding view at the end of the transition. For the view being covered during the presentation, the value returned by this method might be CGRectZero but it might also be a valid frame rectangle.

Navigation controller custom transition animation, To do a custom transition with navigation controller ( UINavigationController ), you should: Define your view controller to conform to  In the Navigation editor, click on the action where the animation should occur. In the Animations section of the Attributes panel, click the dropdown arrow next to the animation you'd like to add. You can choose between the following types: Entering a destination. Exiting a destination.

Using Rob's & Q i's perfect answers, here is the simplified Swift code, using the same fade animation for .push and .pop:

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

        //INFO: use UINavigationControllerOperation.push or UINavigationControllerOperation.pop to detect the 'direction' of the navigation

        class FadeAnimation: NSObject, UIViewControllerAnimatedTransitioning {
            func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
                return 0.5
            }

            func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
                let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
                if let vc = toViewController {
                    transitionContext.finalFrame(for: vc)
                    transitionContext.containerView.addSubview(vc.view)
                    vc.view.alpha = 0.0
                    UIView.animate(withDuration: self.transitionDuration(using: transitionContext),
                    animations: {
                        vc.view.alpha = 1.0
                    },
                    completion: { finished in
                        transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
                    })
                } else {
                    NSLog("Oops! Something went wrong! 'ToView' controller is nill")
                }
            }
        }

        return FadeAnimation()
    }
}

Do not forget to set the delegate in YourViewController's viewDidLoad() method:

override func viewDidLoad() {
    //...
    self.navigationController?.delegate = self
    //...
}

How to Create a Navigation Transition Like the Apple News App, Implement your custom animation within an animator object that adopts When you push or pop a view controller onto or off of the stack, the  Our custom animator object needs to know if the transition is invoked by a push (being presented) or a pop (being dismissed) action of the navigation controller so we will add a Bool property that

It works both swift 3 and 4

@IBAction func NextView(_ sender: UIButton) {
  let newVC = self.storyboard?.instantiateViewControllerWithIdentifier(withIdentifier: "NewVC") as! NewViewController

  let transition = CATransition()
  transition.duration = 0.5
  transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
  transition.type = kCATransitionPush
  transition.subtype = kCAGravityLeft
  //instead "kCAGravityLeft" try with different transition subtypes

  self.navigationController?.view.layer.add(transition, forKey: kCATransition)
  self.navigationController?.pushViewController(newVC, animated: false)
}

Learn iOS Custom View Controller Animation Transition once for all!, We need to “name” a object / class between this 2 view controllers to perform our custom animation transition, think like we call a layer between  If you need to actually push the new viewcontroller using the navigation controller you need to make sure you do this after the animation has finished otherwise the old view will not be displayed. To do so you need to use the setAnimationDelegate method to get notified of when the animation is complete and pass in a selector method to be called.

iOS Animation Tutorial: Custom View Controller Presentation , Transitions are always called with the same UIKit method: present(_:animated:​completion:) . This method  Learn how to implement custom view controller transition. Create a Circular Transition Animation (Custom UIViewController How To Use The Navigation Controller In Xcode 8 (Swift

Custom UIViewController Transitions: Getting Started , Whenever you present or dismiss a view controller, UIKit asks its transitioning delegate for an animation controller  Transitions are always called with the same UIKit method: present(_:animated:completion:). This method “gives up” the current screen to another view controller using the default presentation animation to slide the new view up to cover the current one.

Custom Navigation Transitions, Part III: A Complex Push/Pop , Here's the push/pop transition animation we'll be building today: Note: This is a long We'll have a UINavigationController that conforms to  To present a view controller using custom animations, do the following in an action method of your existing view controllers: Create the view controller that you want to present. Create your custom transitioning delegate object and assign it to the view controller’s transitioningDelegate property.

Comments
  • @Rob Urgh I'm sorry if this sounds idiotic but how do I make my view controller the navigation controller's delegate? I can't seem to bind them on the storyboard and my 'navigationController:animationControllerForOperation: fromViewController:toViewController:' never get called.
  • You can just do self.navigationController.delegate = self; in viewDidLoad. You might get a warning unless you also specify in the @interface line that your view controller conforms to <UINavigationControllerDelegate> protocol.
  • This code is swift 4 for circular transition. stackoverflow.com/a/49321985/8334818
  • best tutorial yet.
  • Vote+, this is the correct way to implement transition animation embedded in navigation controller.
  • Along with that how to retain the default swipe to back (Screen Edge Gesture)?
  • Rob is killing it!
  • @Pavan - Your animationControllerForOperation can just check the fromVC and/or toVC, and return nil if you don't want it to perform custom animation. Simplest is to just check to see if it's a particular class. More elegantly, you might design an optional protocol to which view controllers can conform, with some boolean property to indicate whether they want the custom push/pop or not.
  • Wow, THIS fixes my problem. Why does this piece of information seem to be nowhere else that I looked? Like Apple documentation, other tutorials... It makes no sense to me that you have to set this.
  • Point being that I am using autolayout and set the frame nowhere else...
  • This is a pure gem!