Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling orientation / rotation with storyboards on iOS 6

So.... I've just spent the entire afternoon on this, seen various posts and tried a bunch of things to get this to work, with no luck. I've now taken this back to as simple a case as I can and it still doesn't seem to work.

In this simple scenario, I have a storyboard containing just a UINavigationController and a single initial view controller: enter image description here

Having seen all the posts about the changes to the auto-rotation methods in IOS 6, I've created a subclass of UINavigationController, and implemented the shouldAutorotate and supportedInterfaceOrientations methods both on this sub-class and on the first view controller:

Navigation Controller:

// NavController.h
#import <UIKit/UIKit.h>

@interface NavController : UINavigationController

@end

// NavController.m
#import "NavController.h"

@interface NavController ()

@end

@implementation NavController

- (BOOL) shouldAutorotate {
    return YES;
}

- (NSUInteger) supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}

@end

First Controller

// FirstController.h
#import <UIKit/UIKit.h>

@interface FirstController : UIViewController

@end

// FirstController.m
#import "FirstController.h"

@interface FirstController ()

@end

@implementation FirstController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}

@end

Project settings specify that all rotations should be supported: enter image description here

None of this seems to have any effect...! When I run this in the simulator I get:

enter image description here

enter image description here

Please..! What am I missing here? This is driving me crazy! I'd like to at least get this simple case working so I can stand a hope of getting my fairly large app to work!

like image 854
John Martin Avatar asked Sep 23 '12 16:09

John Martin


3 Answers

If you plan to enable or disable rotation for all view controllers you don't need to subclass UINavigationController. Instead use:

   -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

in your AppDelegate.

If you plan to support all orientations in your app but different orientations on Parent View Controllers (UINavigationController stack) you should use

   -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 

in combination with the following methods in your Parent View Controller.

    - (BOOL)shouldAutorotate

and

- (NSUInteger)supportedInterfaceOrientations

But if you plan to have different orientation settings in different Children ViewControllers in the same navigation stack (like me) you need to check the current ViewController in the navigation stack.

I've created the following in my UINavigationController subclass:

    - (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    int interfaceOrientation = 0;

    if (self.viewControllers.count > 0)
    {
        id viewController;
        DLog(@"%@", self.viewControllers);
        for (viewController in self.viewControllers)
        {
            if ([viewController isKindOfClass:([InitialUseViewController class])])
            {
                 interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
            }
            else if ([viewController isKindOfClass:([MainViewController class])])
            {
                 interfaceOrientation = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
            }
            else
            {
                 interfaceOrientation = UIInterfaceOrientationMaskAllButUpsideDown;
            }
        }
    }
    return interfaceOrientation;
}

Since you cannot control anymore from children ViewControllers the rotation settings of presented view controller you must somehow intercept what view controller is currently in the navigation stack. So that's what I did :). Hope that helps !

like image 188
Razvan Avatar answered Sep 20 '22 02:09

Razvan


Thanks for the suggestions guys.... after HOURS more digging I finally found out what was wrong.

For some reason, even though in the project settings I'd specified all orientations as supported, Xcode wasn't updating the app's Info.plist properly!

For the example project I created, Xcode had only added two values to the Supported Interface Orientations (iPad) dictionary:

 - Portrait (top home button)
 - Portrait (bottom home button)

Adding the two missing orientations finally made the app rotate correctly:

 - Landscape (left home button)
 - Landscape (right home button)

enter image description here

No ideas why these weren't being set correctly. What a frustrating day!

Thanks again for your help.

like image 33
John Martin Avatar answered Sep 21 '22 02:09

John Martin


Post your AppDelegate->didFinishLaunchingWithOptions method.

It should be like this:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//    // Override point for customization after application launch.
//    self.window.backgroundColor = [UIColor whiteColor];
//    [self.window makeKeyAndVisible];
    return YES;
}
like image 26
Tamal Avatar answered Sep 18 '22 02:09

Tamal