0
votes

My app supports two groups of viewControllers, those that are supposed to work in portrait and those who are supposed to work in landscape.

Presenting viewControllers of different orientations from each other results in wrong orientations, so someone suggested me to create a viewController containment master viewController (making that shoulAutorotate YES to all orientations) and add two branches of viewControllers from that, one for portrait (with shouldAutorotate YES for portrait) and one for landscape (with shouldAutorotate YES for landscape). My question is: will this work? I mean, will each viewController on each branch rotate to the correct orientation?

Another question is this: my project is based on the single view Xcode template. That template creates a RootViewController as the one that shows when the app starts. My problem is this: to make the containment suggestion works I have to transform this rootViewController in the container viewController and I have to move all the code it has to another view controller and present that when the app starts. I mean this:

WHAT I HAVE TODAY

  • the app runs and shows the rootViewController. Lets call this vCA.

If I chabge the rootViewController to be the container viewController I will have this

  • the app runs and shows the containerController that is completely empty and has to present the old vCA.

It appears to me a dumb solution, I mean, present the containerController that is empty and will call vCA?

How do I do that?

thanks.

1

1 Answers

0
votes

Your question is kind of confusing since you use the term present, as in a modal ViewController but you also mention containment which would create a different solution.

It all depends on your app really. If one branch of ViewControllers is only portrait and the other only landscape then using containment is probably going to be difficult because of the moment you switch between the two. Orientation calls are passed from the parent to the children but they are only called when a rotation occurs. So for example, your phone is in portrait and you're viewing the portrait VC, when you switch to the landscape VC it will appear in portrait, when you rotate the device the orientation calls will make it go landscape and prevent it from going back to portrait. The same goes the other way around. There is a trick to force the device to go through all orientation callbacks of each ViewController and thus force a rotation, but I'm not sure it works in every iOS version. You can remove the view of the rootViewController from its superview (the window) and immediately add it again which will trigger the orientation callbacks. So you could try to do that every time you switch between child ViewControllers.

Or instead of using containment, you could use the portrait VC as your rootViewController, create the landscape ViewController and store it somewhere so it remains in memory. When you need to show the landscape ViewController you present it modally on the rootViewController. If your autorotation methods are set correctly, it will change the orientation of the status bar and show the VC in the correct orientation. When you dismiss it the orientation will return to portrait.

Edited:

I don't have Xcode here but I typed up something quick in notepad. This should work, it'll force the device to switch orientations, in this case without transition. If you want to use an animation, take a look at the modalTransitionStyle property of _landscapeVC.

// In AppDelegate.h
PortraitViewController* _portraitVC;
LandscapeViewController* _landscapeVC;

// In AppDelegate.m
-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    _portraitVC = [[PortraitViewController alloc] init];
    _landscapeVC = [[LandscapeViewController alloc] init];

    self.window.rootViewController = _portraitVC;
    [self.window makeKeyAndVisible];
}

-(void)showLandscape
{
    [_portraitVC presentViewController:_landscapeVC animated:NO completion:^{}];
    [UIApplication sharedApplication].statusBarOrientation = _landscapeVC.interfaceOrientation;
}

-(void)showPortrait
{
    [_landscapeVC dismissViewControllerAnimated:NO completion:^{}];
    [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
}