I released a project called TRVSNavigationControllerTransition. The project adds convenient methods to translate the entire UINavigationController’s view while pushing and popping UIViewControllers to and from UINavigationControllers, rather than translating the viewController’s view — which is how UINavigationController’s pushViewController:animated: works.
These images illustrate the difference. In the first image, the navigation controller translate’s the view controller’s view. The problem: if the view controller that’s pushed hides the navigation bar, then the navigation bar will suddenly and awkwardly hide during the push.
In the second image, using TRVSNavigationControllerTransition, the navigation controller translate’s the navigation controller’s view. So the navigation bar remains view until the animation’s finished.
How to make your own transition
TRVSNavigationControllerTransition works like this:
- Take a snapshot of the current view in the form of a CALayer and add it as a sublayer of the current view.
- Push or pop the next view without animation.
- Take a snapshot of the new view in the form of a CALayer.
- Add whatever animations you want to those layers for their transition.
- Remove the layers from their superlayer once the transition animation finishes.
See UINavigationController+TRVSNavigationControllerTransition.m for more details.
I saw others using a CATransition, like so:
CATransition* animation = [CATransition animation]; animation.duration = 0.3f; animation.type = kCATransitionPush; animation.subtype = kCATransitionFromRight;
The problem is that kCATransitionPush’s animation looks different from UINavigationController’s pushViewController:animated:. It doesn’t fit.
To use TRVSNavigationControllerTransition, link your binary with the QuartzCore.framework library. Then in your code write:
[self.navigationController pushViewControllerWithNavigationControllerTransition:viewController]; [self.navigationController popViewControllerWithNavigationControllerTransition];