0
votes

I have read several other questions (and answers) regarding the same issue, but could not find a single working solution for my case.

I am developing an iOS app for iOS7 using Storyboards. This app is composed by multiple UIViewControllers. All of them but one MUST be displayed only with the Portrait interface orientation. My problem is that all the views rotate when they should not.

In the XCode project settings I tick the Portrait and Landscape Left device orientations.

The related Apple docs are available at the following URLs: Controlling What Interface Orientations Are Supported (iOS 6), supportedInterfaceOrientations and preferredInterfaceOrientationForPresentation.

I added to all the UIViewControllers in the Storyboad (but the one that can rotate) the following methods:

- (BOOL) shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
   return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

Unfortunately all the views rotate to landscape left position. Why?

3

3 Answers

0
votes

You need to add more code to the method - (BOOL) shouldAutorotatelike this for portrait orientation

- (BOOL)shouldAutorotate{

    if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait) {

        return YES;
    }
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {

    NSLog(@"rotate");

}

And you will need to add in your App Delegate this method

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window  // iOS 6 autorotation fix {
    return UIInterfaceOrientationMaskAll;
}
0
votes

Got the solution from here: iOS6: supportedInterfaceOrientations not working (is invoked but the interface still rotates).

I did not find that question before writing mine. Sorry about that.

The problem is in the Apple Documentation. In one place they write this:

When a view controller is presented over the root view controller, the system behavior changes in two ways. First, the presented view controller is used instead of the root view controller when determining whether an orientation is supported.

Where you think that the decision is made by the UIViewController occupying the screen.

And in the UIViewController class reference they write this:

Typically, the system calls this method only on the root view controller of the window or a view controller presented to fill the entire screen; child view controllers use the portion of the window provided for them by their parent view controller and no longer participate directly in decisions about what rotations are supported. The intersection of the app’s orientation mask and the view controller’s orientation mask is used to determine which orientations a view controller can be rotated into.

From which you should understand that with a UINavitationController the first sentence does not apply.

0
votes

Be sure Portrait, Landscape Right and Landscape Left orientations are enabled in your project. Then, if you want to block some orientations for a particular view:

– application:supportedInterfaceOrientationsForWindow:

If you want to force an orientation for a particular view, check the question How to handle different orientations in iOS 6. See the answer there for a project example of exactly what you need.

Basically you need to embed a custom navigation controller in your viewcontroller (the one you want to rotate). Add the following method in this custom navigation controller

- (NSUInteger)supportedInterfaceOrientations
{
    return self.topViewController.supportedInterfaceOrientations;
}

and add to your view controller that should rotate:

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}