49

So I followed this thread: RootViewController Switch Transition Animation to transit the window.rootViewController from A to B to C. Code looks like this:

[UIView transitionWithView:self.window 
                  duration:0.5 
                   options: UIViewAnimationOptionTransitionFlipFromLeft 
                animations:^{
                               self.window.rootViewController = newViewController;
                } 
                completion:nil];

The problem is my app shall only support landscape, but during the rootViewController transition, the new view controller appears in portrait mode than quickly rotate to landscape mode.

I'm sure that:

  1. I've set UISupportedOrientation to landscape (home button right)
  2. for each viewcontroller, in the shouldAutoRotateToOrientation method, I set only for landscape

What could be the other reason?

Community
  • 1
  • 1
Chris Chen
  • 5,307
  • 4
  • 45
  • 49

2 Answers2

120

I looked into this just now because I kept getting the same issue. I randomly tried the following, and it worked perfectly:

[UIView
    transitionWithView:window 
    duration:0.5
    options:UIViewAnimationOptionTransitionCrossDissolve
    animations:^(void) {
        BOOL oldState = [UIView areAnimationsEnabled];
        [UIView setAnimationsEnabled:NO];
        [(ICApp *)sharedApplication.delegate window].rootViewController = self;
        [UIView setAnimationsEnabled:oldState];
    } 
    completion:nil];

I know it's a bit odd to disable/enable animations inside an animation block, but the cross dissolve animates, and the rotation does not -- the view controller appears already rotated and ready to roll.

Kalle
  • 13,186
  • 7
  • 61
  • 76
  • Thanks, this fixed other visual craziness that had nothing to do with rotation. I edited it to include preserve the original animation state, rather than assuming it should be YES. – benzado Jan 05 '12 at 00:05
  • Doesn't seem to be working for me on iOS 6? Can anyone else confirm? – Steve Sep 29 '12 at 16:36
  • 1
    does work for me on iOS 6. It makes sense that it works as disabling the animation would only affect animations that are submitted afterwards – Edward Huynh Dec 07 '12 at 04:36
  • 1
    Works on iOS 6 for me as well. – Kalle Dec 07 '12 at 12:47
  • Works on iOS 6 for me! Still don't quite understand why the fix works, though. – Joseph Lin May 20 '13 at 20:42
  • This solution works much more perfect than answers exists out there for all similar questions! Works good in iOS 7. Btw, how can I make a slide up/down transition? – Greg Wang Dec 12 '13 at 21:13
  • Just found, this animation cause warning `Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.` in iOS 7 simulator. Any thought on this? – Greg Wang Dec 12 '13 at 21:25
  • I don't get that warning myself -- and it's not doing snapshotting, from what I can tell. Maybe post a separate question and link here and include your code? – Kalle Dec 19 '13 at 04:19
  • Works perfect on iOS7! – Gary Lyn Jan 03 '14 at 12:07
  • This solution works perfect on ios6 and ios7 (and both sizes). I tested a lot of similar solutions and it is the best. I don't understand why this helps me also with other visual problems, but Thanks! – Ramiro May 07 '14 at 11:38
  • Nice trick. This prevents animating the content of the new rootViewController. I first had to experiment a lot on the internal stuffs, thought it had to do something with it. But no, it's actually at the top level -- the window.rootVC transitioning. – MkVal Jun 27 '14 at 03:54
  • Definitely works. iOS7.1. Works better than other very similar solutions. – micnguyen Aug 18 '14 at 07:54
9

Just put in another animation option UIViewAnimationOptionAllowAnimatedContent:

[UIView transitionWithView:self.window duration:0.5 options:(UIViewAnimationOptionTransitionFlipFromLeft | UIViewAnimationOptionAllowAnimatedContent) animations:^{
    self.window.rootViewController = newViewController;
} completion:nil];
Borut Tomazin
  • 8,041
  • 11
  • 78
  • 91
  • This doesn't work for me. The new view controller still appears in portrait mode then rotates to landscape mode, as described in the question. – Kristopher Johnson Mar 21 '13 at 21:14
  • For any one who reading this for iOS 8.3 this is only looks "good" with Flip transitions but still shows some controllers resizing in target controller. Using setAnimationsEnabled gives way nicer visual effect. – CryingHippo May 03 '15 at 11:50
  • great answer to allow objects to animate along the transitioned view – Fede Cugliandolo May 17 '16 at 05:23