What is going to happen down here are basically UIView animations combined with UIViewControllerAnimatedTransitioning and UINavigationControllerDelegate . No big deal but pretty cool in case you’re done with push, modal and fade transitions.

Let’s create a blank project and two UIViewControllers in which we’ll work on the transition. Each one of these must have an UIImageView to be used as start/end of the transition and we need to enable user interactions so we can add a UITapGestureRecognizer .

We have the UIImageView as an @IBOutlet

as an On our viewDidLoad we setup the UITapGestureRecognizer and it calls a function to navigate to OtherViewController .

Before we start talking about TransitionDelegate , let’s see what’s in the OtherViewController .

AnimatedTransition

This protocol will handle the UIImageView that will be part of the transition and will be used as a conforming validator, whether the transition should be this one we’re creating or just a regular transition. We’re also including an enum for the transition states, so we can define what is appearing/hiding.

TransitionDelegate

This will conform to:

UIViewControllerAnimatedTransitioning which will force us to implement two functions: transitionDuration & animateTransition . The magic happens with them, so I separated them on an extension we’ll see right after this.

which will force us to implement two functions: & . The magic happens with them, so I separated them on an extension we’ll see right after this. NSObject simply because UIViewControllerAnimatedTransitioning conforms to NSObjectProtocol .

simply because conforms to . UINavigationControllerDelegate .

Honestly, it doesn’t have to conform to UINavigationControllerDelegate , I could have used a different entity as delegate and return an instance of TransitionDelegate as we will talk about in the last snippet I’ll insert here.

Within configureViews which will get called two times — one when the transition starts and one when it ends — we have the image that will start the transition, the image that will finish the transition and the image that will be scaled. It contains the same UIImage , I get it. But the UIImageView has the frame info which will be important for the convert method which takes us to the state switch .

Calling convert will convert the frame of the UIImageView passed as snapshotView from the start frame to the end frame.

I really like to separate protocol conforming into extensions, makes it clear for me what comes from where. So, here we have UIViewControllerAnimatedTransitioning which again, obligates us to implement these two functions. The first one will just return the duration constant. The second one will define what happens during the transition.

Step by step

We have both UIViewControllers — fromVC and toVC — and we have the containerView which will further insert the snapshotView containing the UIImageView which will have its frames converted from the start to the end imageView. Phew… It seems complicated but it’s not.

Next, we call AnimatedTransition protocol imageView function on both fromVC and toVC, and since they conform to this protocol, we will get the start/end UIImageViews .

Now that we have all the views, we will do a hiding/appearing game with background/foreground images so it hides everything except for the snapshotView during the animation and the other way round when the animation is done. For this, a simple UIView animation with completion block. Finally, on the completion block, we call completeTransition and toVC will start calling it’s lifecycle method chain (viewDidAppear etc…)

Once we’re all set, we need to validate whether the UINavigationController will use this animation or not:

And that’s it. I hope you guys liked the article and let me know if I can help with anything!