Anton
Anton

Reputation: 2297

UINavigationController and Alternate Landscape

In my application I use an Alternate Landscape Interface strategy (present your landscape view as a modal). I also use a navigation controller for transitioning and this causes the following problem: I dunno how to push/pop correctly from landscape orientation.

I came up with the following solution, but someone may know a better one. Suppose one has to deal with only two views. Let's call them AP, AL, BP, BL, where the second letter stands for orientation. We start with a navigation controller with AP inside. To go between AP and BP we just push/pop. To go from AP to AL we present a modal navigation controller with AL inside. To go between AL and BL we push/pop inside the second navigation controller. Now to go from BP to BL we pop w/o animation and present a modal navigation controller with BL sitting on top of AL. To go from BL to BP we dismiss the modal navigation controller and push BP w/o animation.

Seems to be a bit ugly, but not so bad. Can anyone think of something better?

Thanks in advance!

Upvotes: 4

Views: 681

Answers (1)

simeon
simeon

Reputation: 4626

Is there some reason you need to present your landscape orientation as modal in a separate controller? When I have two entirely different views for my portrait and landscape orientations I fade between them as they stretch during the rotation.

This allows for vastly different content in both orientations, a nice transition between them, and shared code under one controller.

Here is some code. Our UIViewController will switch between portraitView and landscapeView when we change orientation.

portraitView and landscapeView are both children of the UIViewController's view. The hierarchy looks as follows:

UIViewController
    |
     - view
        |
        |- portraitView
        |
        |- landscapeView

Both have their autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight to ensure that they stretch as the view controller rotates.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    if( orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight )
    {
        [UIView animateWithDuration:duration
                         animations:^
                         {
                             //Fade the landscape view over the top of the 
                             //portrait view as during rotation 
                             landscapeView.alpha = 1.0f;
                         }
                         completion:^(BOOL finished)
                         {
                             //Hide the portrait view when landscape is fully
                             //visible
                             portraitView.alpha = 0.0f
                         }];
    }
    else
    {
        //Show the portrait view (underneath the landscape view)
        portraitView.alpha = 1.0f;

        [UIView animateWithDuration:duration
                         animations:^
                         {
                             //Fade out the landscape view to reveal the portrait view
                             landscapeView.alpha = 0.0f;
                         }];
    }
}

Your controls and subviews will fade and deactivate along with the appropriate views, allowing you to have completely different content. I used this recently to fade between two different background images when changing orientation. The effect is very smooth.

You can now create your two view controllers, A and B which each manage two views as described above. You can then simply push the view controllers as normal and not have to worry about managing the UINavigationController's view controller stack during rotation.

Upvotes: 1

Related Questions