IOS 6 force device orientation to landscape

2019-01-03 07:44发布

I gave an app with say 10 view controllers. I use navigation controller to load/unload them.

All but one are in portrait mode. Suppose the 7th VC is in landscape. I need it to be presented in landscape when it gets loaded.

Please suggest a way to force the orientation go from portrait to landscape in IOS 6 (and it will be good to work in IOS 5 as well).

Here is how I was doing it BEFORE IOS 6:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    UIViewController *c = [[[UIViewController alloc]init] autorelease];
    [self presentModalViewController:c animated:NO];
    [self dismissModalViewControllerAnimated:NO];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

Presenting and dismissing a modal VC was forcing the app to review its orientation, so shouldAutorotateToInterfaceOrientation was getting called.

What I have have tried in IOS 6:

- (BOOL)shouldAutorotate{
    return YES;
}
-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    return UIInterfaceOrientationLandscapeLeft;
}

On load, the controller keeps staying in portrait. After rotating the device, the orientation changes just ok. But I need to make the controller to rotate automatically to landscape on load, thus the user will have to rotate the device to see the data correctly.

Another problem: after rotating the device back to portrait, the orientation goes to portrait, although I have specified in supportedInterfaceOrientations only UIInterfaceOrientationMaskLandscape. Why it happens?

Also, NONE of above 3 methods are getting called.

Some (useful) data:

  1. In my plist file I have specified 3 orientations - all but upside down.
  2. The project was started in Xcode 4.3 IOS 5. All classes including xibs were created before Xcode 4.5 IOS 6, now I use the last version.
  3. In plist file the status bar is set to visible.
  4. In xib file (the one I want to be in landscape) the status bar is "None", the orientation is set to landscape.

Any help is appreciated. Thanks.

13条回答
走好不送
2楼-- · 2019-01-03 08:31

I solved it by subclassing UINavigationController and overriding the supportedInterfaceOrientations of the navigation Controller as follow:

- (NSUInteger)supportedInterfaceOrientations
{
     return [[self topViewController] supportedInterfaceOrientations];
}

All the controllers implemented supportedInterfaceOrientations with their desired orientations.

查看更多
成全新的幸福
3楼-- · 2019-01-03 08:32

I had the same problem, 27 views in my application from which 26 in portrait and only one in all orientations ( an image viewer :) ). Adding the macro on every class and replace the navigation wasn't a solution I was comfortable with...

So, i wanted to keep the UINavigationController mechanics in my app and not replace this with other code.

What to do:

@1 In the application delegate in method didFinishLaunchingWithOptions

if ([[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
    // how the view was configured before IOS6
    [self.window addSubview: navigationController.view];
    [self.window makeKeyAndVisible];
}
else
{
    // this is the code that will start the interface to rotate once again
    [self.window setRootViewController: self.navigationController];
}

@2 Because the navigationController will just responde with YES for autorotation we need to add some limitations: Extend the UINavicationController -> YourNavigationController and link it in the Interface Builder.

@3 Override the "anoying new methods" from navigation controller.

Since this class is custom only for this application it can take responsibility for it's controllers and respond in their place.

-(BOOL)shouldAutorotate {

    if ([self.viewControllers firstObject] == YourObject)
    {
         return YES;
    }
    return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
     if ([self.viewControllers firstObject] == YourObject)
    {
         return UIINterfaceOrientationMaskLandscape;
    }
    return UIInterfaceOrientationMaskPortrait;
}

I hope this will help you,

查看更多
冷血范
4楼-- · 2019-01-03 08:34

Try segueing to a UINavigationController which uses a category or is subclassed to specify the desired orientation, then segue to the desired VC. Read more here.

查看更多
狗以群分
5楼-- · 2019-01-03 08:37

I had the same problem. If you want to force a particular view controller to appear in landscape, do it right before you push it into the navigation stack.

UIInterfaceOrientation currentOrientation = [[UIApplication sharedApplication] statusBarOrientation];
        if (currentOrientation == UIInterfaceOrientationPortrait ||
            currentOrientation == UIInterfaceOrientationPortraitUpsideDown)
            [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeLeft];

        UIViewController *vc = [[UIViewController alloc] init];
        [self.navigationController pushViewController:vc animated:YES];
        [vc release];
查看更多
一纸荒年 Trace。
6楼-- · 2019-01-03 08:40

This should work, it's similar to the pre-iOS 6 version, but with a UINavigationController:

UIViewController *portraitViewController = [[UIViewController alloc] init];
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:portraitViewController];
[self.navigationController presentModalViewController:nc animated:NO];
[self.navigationController dismissModalViewControllerAnimated:NO];

I'm calling this before I'm pushing the next UIViewController. It will force the next pushed UIViewController to be displayed in Portrait mode even if the current UIViewController is in Landscape (should work for Portrait to Landscape too). Works on iOS 4+5+6 for me.

查看更多
叛逆
7楼-- · 2019-01-03 08:40

I think that best solution is to stick to official apple documentation. So according to that I use following methods and everything is working very well on iOS 5 and 6. In my VC I override following methods:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}

Methods for iOS 6, first method returns supported orientation mask (as their name indicate)

-(NSUInteger)supportedInterfaceOrientations{

    return UIInterfaceOrientationMaskPortrait;
}

second one thats tells your VC which is preferred interface orientation when VC is going to be displayed.

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}

Just change Portrait for orientation that you want ;) This solution is working smooth, I don't like the idea of creating macros and other stuff, that goes around this simple solution. Hope this help...

查看更多
登录 后发表回答