iOS 6 Rotation issue - No rotation from Presented Modal View Controller

I have a MainViewController which has a button which pushes a new view (InfoViewController), via flip horizontailly. like so:

controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];

The MainView Controller supports Portrait and PortraitUpsideDown. Like so:

- (BOOL)shouldAutorotate {
    return YES;    
}

- (NSUInteger)supportedInterfaceOrientations {    
    return (UIInterfaceOrientationMaskPortrait | 
            UIInterfaceOrientationMaskPortraitUpsideDown);
}

In my InfoViewController it also states the above code. In my AppDelegate it has this in the LaunchOptions:

[self.window setRootViewController:self.mainViewController];

In my app.plist file it supports all orientations. This is because other views need to support landscape as well. So On my MainViewController and InfoViewController I need only Portrait and PortraitUpsideDown. But on another view I need all orintations.

My MainViewController works fine, but my InfoViewController is working for all orientations.

I am having extreme diffulty trying to get this to work in iOS6. I have researched other posts and tried the assistance other people have provided, but had no luck whatsoever. Please can someone help me acheive this thank you. And I'm a Objective-C newbie :p


Solution 1:

Don´t support all orientations in your app plist file, only those that your root view controller supports.

Autorotation is changing in iOS 6. In iOS 6, the shouldAutorotateToInterfaceOrientation: method of UIViewController is deprecated. In its place, you should use the supportedInterfaceOrientationsForWindow: and shouldAutorotate methods:

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAllButUpsideDown;    
}

Modal ViewControllers no longer get rotation calls in iOS 6: The willRotateToInterfaceOrientation:duration:, willAnimateRotationToInterfaceOrientation:duration:, and didRotateFromInterfaceOrientation: methods are no longer called on any view controller that makes a full-screen presentation over itself—for example those that are called with: presentViewController:animated:completion:.

You can let the view controller that presents your modal view controller inform it of rotation. Also, now you use: presentViewController:animated:completion: to present the view controller. presentModalViewController:animated: is deprecated which you use in the code.

Solution 2:

I have solved similar problems, while using tab bar controller.

Subclass UITabBarController. Implement these methods:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}


- (BOOL)shouldAutorotate
{
    NSLog(@"Orientation:%d", [[UIDevice currentDevice] orientation]);

    for (UIViewController *viewController in self.viewControllers) {
        [viewController shouldAutorotate];
    }

    return YES;
}

If you want to handle rotations in controllers inside tabbarcontroller, in each of the controllers in the tab bar controller implement those methods too and write code to handle orientation change. If you don't want to handle it, then you don't need to implement those methods. TabBarControllers methods will always run when orientation changes. Even twice for unknown reason.

Yes, and don't forget to delete all shouldAutorotate methods. I moved to the new orientation model completely. If you want to make them remain, probably, it will be harder.