In iOS 5, my application I used the method to change my orientation:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
In iOS 6 I think I'm supposed to do this, but it does nothing! My app is rotated not the way I want it to be.
- (BOOL) shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight;
}
It's how I was adding my viewController
.
I replaced this line code:
[window addSubview:viewController.view];
by this line:
[window setRootViewController:viewController];
When the device changes orientation, in iOS 6, the system asks the application which orientation it supports. The application will return a number of orientations it accepts.
How does the application determine it's orientation?
- First the application checks it's info.plist orientations (this is very important to determine which orientation to use for launch.
- Secondly it asks it's application delegate for it's orientations, this can be specified via the
-(NSUInteger)application:supportedInterfaceOrientationsForWindow:
method. This effectively overrides the info.plist setting, this implementation is optional. By default iPad apps orientate in all directions and iPhone in all but upside down.
- Lastly the application delegate queries it's top most view controller, this can be a
UINavigationController
or a UIViewController
... etc, then it specifies how to be presented and if it wants to autorotate. These UIViewControllers
can use shouldAutorotate:
and supportedInterfaceOrientations
methods to tell the app delegate how to present it.
You must make sure you set the root view controller of your window.
Also if you are presenting any other view controllers in full screen such as a modal view controller, this is the one responsible for determining orientation changes or not.
For me the solution worked, the case was different a bit, because I had a UINavigationController
.
My case was that I needed all Portrait window except one. I had to enable all landscape and the portrait orientations in targets (otherwise it crashes on the only landscape view).
So in this case:
- create a subclass for
UINavigationController
,
- insert the rotationspecific stuff there
- and use the subclass instead of
UINavigationController
.
If you are using a UINavigationController, it sends the supportedInterfaceOrientations:
message to the UINavigationController itself rather than the top most view controller (i.e. what you would actually want it to do).
Instead of having to subclass UINavigationController to fix it, you can simply add a category to UINavigationController.
I created a new variable in my singleton: canRotate
, and I set it to YES when I want the viewcontroller to support some orientation.
In appDelegate I added this:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if([[SharedData sharedInstance] canRotate])
{
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight);
}
return UIInterfaceOrientationMaskPortrait;
}
in my case it works. I have a custom tabbar and UINavigationviewControllers are added as subviews to rootViewController.
I know this sounds pretty elementary, but I was wracking my brain to figure out orientation issues while testing on my iPhone - I had the physical auto lock mode in Portrait mode - so nothing I changed programmatically mattered - thought this should be troubleshooting step number 1!