I have seen lots of people asking on how to push/pop UINavigationControllers using other animations besides the default one, like flip or curl.
One problem that you will find is that either the question/answer was relatively old, which means that it included have some things not used anymore like
[UIView beginAnimations:] and
[UIView commitAnimations] (example here) but if you searched enough you will see the use two different approaches nowadays
UIView Animations only
The first is to use UIView‘s
transitionFromView:toView:duration:options:completion: selector before pushing the controller (with the animation flag set to
NO), like the following:
UIViewController *ctrl = [[UIViewController alloc] init]; [UIView transitionFromView:self.view toView:ctrl.view duration:1 options:UIViewAnimationOptionTransitionFlipFromTop completion:nil]; [self.navigationController pushViewController:ctrl animated:NO];
This is pretty straightforward and might be good enough for most projects as the options parameter gives you some nice transitions by default:
One key aspect is to note that the
animated: parameter is set to
NO, as we are performing the animation from one view to another manually, avoiding the default one that the
Ok, but sometimes you want some more radical animations, and thats when Core Animation calls you to action
This second approach uses CoreAnimation explicitly with a
CATransaction like the following:
CATransition* transition = [CATransition animation]; transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; transition.duration = 1.0f; transition.type = @"flip"; transition.subtype = @"fromTop"; [self.navigationController.view.layer removeAllAnimations]; [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; UIViewController *ctrl = [[UIViewController alloc] init]; [self.navigationController pushViewController:ctrl animated:NO];
First observation, you will have to have the QuartzCore framework added to your project for this approach and also add
<QuartzCore/QuartzCore.h> to the class this code is used to make it work.
There are several aspects that this approach differs from the first one. The main one is that the first one results in a code that looks a lot cleaner the the Core Animation one, but there is a big trade-off as CoreAnimation opens the gate to several really cool transitions like “suckEffect”, “cube”, and others. Here is a list of some of the possible native effects.
- fade (kCATransitionFade)
- moveIn (kCATransitionMoveIn)
- push (kCATransitionPush)
- reveal (kCATransitionReveal)
- genieEffect …
As you might have noticed, a lot of the transitions does not have a native constant value, so you might get worried about using these undocumented transitions types (i.e. not present in the Common transition types documentation from CATransition Class Reference) which could get your app rejected from App Store (I mean could as there is no explicit documentation or reference about apps being rejected due to Core Animation transactions). There are some alternatives to perform these kind of animations using openGL, for example, but this is not the focus right now.
Besides UINavigationController transition
I believe you noticed that the transitions I showed were all
UIView transitions, which means they could all be used to animate
UIView, regardless of an UIViewController.
A good example of these flip transitions being used for
UIViews only is inside of Google Places’s App when you tap to change the places view mode from map to list (and vice-versa)
Originally posted by me at http://i.ndigo.com.br/2012/05/ios-uiview-transition-effects/