Portrait and Landscape mode in iOS6

2019-01-14 14:45发布

问题:

When updating my app to iOS6 standard the portrait / landscape is gone. Ir worked perfectly when I was building with Xcode 3. But now using latest Xcode and latest SDK the rotation is gone and it is always in portrait mode. No matter what I put in "Supported interface Orientations". And the code I used to get rotation before seems to have no effect at all. I had these lines.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    switch (toInterfaceOrientation) {
        case UIInterfaceOrientationPortrait:
        case UIInterfaceOrientationLandscapeLeft:
        case UIInterfaceOrientationLandscapeRight:
            return YES;
        default:
            return NO;
    }
}

How do I change and what do I change to get it work again?

回答1:

First of all, in AppDelegate, write this. THIS IS VERY IMP

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
     return (UIInterfaceOrientationMaskAll);
}

Then, For UIViewControllers, in which you need only PORTRAIT mode, write these functions

- (BOOL)shouldAutorotate
{
     return YES;
}

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

For UIViewControllers, which require LANDSCAPE too, change masking to All.

- (NSUInteger)supportedInterfaceOrientations
{
    return (UIInterfaceOrientationMaskAllButUpsideDown);
    //OR return (UIInterfaceOrientationMaskAll);
}

Now, if you want to do some changes when Orientation changes, then use this function.

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

}

EDIT :

A lot depends on with which controller is your UIViewController embedded in.

Eg, If its inside UINavigationController, then you might need to subclass that UINavigationController to override orientation methods like this.

subclassed UINavigationController (the top viewcontroller of the hierarchy will take control of the orientation.) did set it as self.window.rootViewController.

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

From iOS 6, it is given that UINavigationController won't ask its UIVIewControllers for orientation support. Hence we would need to subclass it.



回答2:

How to support one or more landscape controllers in app that is portrait mainly in ios6:

1) in AppDelegate

 - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
    {
        UINavigationController* ns = (UINavigationController*)self.window.rootViewController;
        if (ns) {
            UIViewController* vc = [ns visibleViewController];
//by this UIViewController that needs landscape is identified
            if ([vc respondsToSelector:@selector(needIos6Landscape)])
                return [vc supportedInterfaceOrientations];

        }
        return UIInterfaceOrientationMaskPortrait; //return default value
    }

2) in UIView controller(s) that needs landscape (or portrait+lanscape etc):

//flag method
-(void)needIos6Landscape {
}
- (BOOL)shouldAutorotate
{
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

3) in controllers, to which you can RETURN from controllers, that can be rotated in landscape - this is important, otherwise they remaind landscape on return from landscape-enabled VC.

- (BOOL)shouldAutorotate
{
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

4) (maybe not needed, but for sure..) - subclass navigation controller(s) you using, and add:

- (BOOL)shouldAutorotate
{
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
    UIViewController* vc = [self visibleViewController];
    if (vc) {
        if ([vc respondsToSelector:@selector(needIos6Landscape)]) {
             return [vc supportedInterfaceOrientations];
        }
    }
    return UIInterfaceOrientationMaskPortrait;
}

The important step is to ask for orientation only controllers from your app, because during transition between controllers, for some time there is some system controller as root, and will return incorrect value (this took me 2 hrs to find out, it was reason it was not working).



回答3:

Don't know whether your issue was alike but with me, the status bar was oriented correctly (landscape) and the UIViewController was portrayed. I changed following line in the application delegate application:didFinishLaunchingWithOptions:

//[window addSubview:navigationController.view];

self.window.rootViewController = navigationController;

Apple=> this costed me a day and a half to find out, and a lot of money!!!