iOS7 Custom Transitions
iOS7 Custom Transitions

iOS7 Series –Custom Transitions

There is a hierarchy of actors you need to visualize here.  It goes a little something like:

  1. A TransitioningDelegate
  2. An AnimatedTransitioning
  3. A ContextTransitioning

The VC you start out with and that will call the transition will adopt the first protocol, the TransitioningDelegate Protocol.  The purpose of doing so is to obtain the authority to manage the entire transition process.

You will then create a Transitioning class which we can call the Transition Manager.  This class will adopt the AnimatedTransitioning protocol.  The purpose of this protocol is to animate the transition.

The Transition Manager class receives all the necessary information from the Transitioning Context (a protocol adopted by a class you wont really see) and it sends that info to the TransitioningDelegate in order for it to call the shots.

The process itself is quite simple.  We create a Transition Manager class, which adopts the AnimatedTransitioning protocol as stated above.  Then we instantiate this class and call its methods from our initial view controller, who has adopted the TransitioningDelegate protocol in order to call the shots.  Voila, our VC calls the transition for us.

So create a subclass of NSObject and call it what you wish, I called it PinRotatingTransitionManager.  Of course make it adopt the AnimatedTransitioning protocol like so:

<UIViewControllerAnimatedTransitioning>

There are 2 methods you must implement in order to adopt this protocol.  The first one is:

//Define the transition duration

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{

return 1.0;

}

As you can see this simply states how long the transition will last.  It returns a value of type NSTimeInterval and takes in the transition context.

The second method is for describing the animation and it’s a bit long so let’s go one step at a time:

//1. Get current state

UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

CGRect sourceRect = [transitionContext initialFrameForViewController:fromVC];

First we get some values for the current state; who is our fromVC, who is our toVC and what is the relevant frame of our current, fromVC.  Remember we are transitioning between two vcs.  The one we are in is called the fromVC or initialVC or if you prefer to keep the original iOS lingo, our sourceVC.  The second one is called our toVC or finalVC or destinationVC.

We need to get a reference to both of them (basically to say THIS vc will do this and THAT vc will do that!).  And of course we need to know the frame we are starting from.

//2.Settings for the fromVC ……………………….

CGAffineTransform rotation;

rotation = CGAffineTransformMakeRotation(M_PI);

fromVC.view.frame = sourceRect;

fromVC.view.layer.anchorPoint = CGPointMake(0.5, 0.0);

fromVC.view.layer.position = CGPointMake(160.0, 0);

We create a rotation transform which will rotate anything by M_PI.  Then we set our fromVC frame to the sourceRect, we define an anchor point for it and a position for it.

//3.Insert the toVC view………………………

UIView *container = [transitionContext containerView];

[container insertSubview:toVC.view belowSubview:fromVC.view];

CGPoint final_toVC_Center = toVC.view.center;

Now we need to do something quite important…get a container view to put everything into in order to run the transition.  To that container view we must add the toVC, because the fromVC is already added for us.

//4.Insert the toVC view………………………

toVC.view.center = CGPointMake(-sourceRect.size.width, sourceRect.size.height);

toVC.view.transform = CGAffineTransformMakeRotation(M_PI/2);

Now we set the toVC’s center point and apply the transform created.

And finally we perform the animation:

//5. Animate..

[UIView animateWithDuration:1.0

delay:0.0

usingSpringWithDamping:.8

initialSpringVelocity:6.0

options:UIViewAnimationOptionCurveEaseIn

animations:^{

//Setup final params of the views

fromVC.view.transform = rotation;

toVC.view.center = final_toVC_Center;

toVC.view.transform = CGAffineTransformMakeRotation(0);

} completion:^(BOOL finished) {

//When done call completeTransition

[transitionContext completeTransition:YES];

}];

This is quite simple.  We define some parameters for the animation and call a block which applies the rotation and center etc.  Once complete we call completeTransition which is mandatory.

Now run your app and you should have a very nice transition where the fromVC slides left and the toVC rotates down into place.

 

Neat huh!

Leave a Reply