I'm having a little trouble swapping rootViewControllers with animation. Here's the code that I'm using:
[UIView transitionWithView:self.window duration:0.8 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{
self.window.rootViewController = self.navigationController;
} completion:nil];
It kind of works except that right before the animation, the screen turns to black and then the animation occurs. It looks like the original rootViewController is getting removed right before the animation. Any ideas?
I am aware this is a quite old question, however, neither the accepted answer nor the alternatives provided a good solution (when the animation finished the navigation bar of the new root view controller blinked from white to the background color, which is very jarring).
I fixed this by snapshotting the last screen of the first view controller, overlaying it over the second (destination) view controller, and then animating it as I wanted after I set the second view controller as root:
EDIT: Swift 3 version of the code:
transitionWithView
is intended to animate subviews of the specified container view. It is not so simple to animate changing the root view controller. I've spent a long time trying to do it w/o side effects. See:Animate change of view controllers without using navigation controller stack, subviews or modal controllers?
EDIT: added excerpt from referenced answer
I have found transitionWithView:duration:options:animations:completion: to produce a more reliable result.
If you leave it until the completion block to set the root view controller then during methods such as view(Will/Did)Appear
Will still be set to the previous view controller. This may not be a problem in most situations unless you need to pass on that reference to the rootViewController to other code during those methods as I did.
The currently accepted answer (at the time of writing this answer) isn't ideal because it might not position UI elements like the navigation bar correctly during the animation or lead to other layout glitches as described in Marko Nikolovski's answer. However, pushing a snapshot of the current view controller's view on top of the next view controller's view for animation purposes isn't ideal either because it cannot be used for view controllers in which any kind of animation is happening during the transition to the next view controller as a snapshot is just a static image.
Taking cclogg's basic idea here's my implementation for a smooth transition between two view controllers that doesn't bother about alpha values:
It's important to replace the window's
rootViewController
before initiating the transition or animation because that's how the new view controller gets to know its context, i.e. the correct layout margins etc.The solution that worked for me was a slight modification of Marko Nikolovski's answer. My existing root view controller had an animated spinner on it, so a snapshot looked weird because it froze the animation. In the end, I was able to do the following (inside the current root view controller):
Instead of swapping rootViewControllers, why don't you create either a custom View, or maybe just a UINavigationController (don't show titlebar) and put the "rootViews" you want to swap between under that.