iOS6: supportedInterfaceOrientations not working (

2019-01-06 13:44发布

In my app I have multiple views, some views need to support both portrait and landscape, while other views need to support portrait only. Thus, in the project summary, I have all selected all orientations.

The below code worked to disable landscape mode on a given view controller prior to iOS 6:

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

Since shouldAutorotateToInterfaceOrientation was deprecated in iOS6 I've replaced the above with:

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMask.Portrait;
}

This method is correctly called when the view appears (I can set a breakpoint to ensure this), but the interface still rotates to landscape mode regardless of the fact that I'm returning the mask for portrait modes only. What am I doing wrong?

It seems that it's currently impossible to build an app that has different orientation requirements per view. It seems to only adhere to the orientations specified in the project summary.

15条回答
▲ chillily
2楼-- · 2019-01-06 14:14

The best way for iOS6 specifically is noted in "iOS6 By Tutorials" by the Ray Wenderlich team - http://www.raywenderlich.com/ and is better than subclassing UINavigationController for most cases.

I'm using iOS6 with a storyboard that includes a UINavigationController set as the initial view controller.

//AppDelegate.m - this method is not available pre-iOS6 unfortunately

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;

if(self.window.rootViewController){
    UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
    orientations = [presentedViewController supportedInterfaceOrientations];
}

return orientations;
}

//MyViewController.m - return whatever orientations you want to support for each UIViewController

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}
查看更多
狗以群分
3楼-- · 2019-01-06 14:16

In my case I have UINavigationController and my view controller inside. I had to subclass UINavigationController and, in order to support only Portrait, add this method:

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

So in the UINavigationController subclass I need to check which orientation is supported by the current topViewController.

- (NSUInteger)supportedInterfaceOrientations
{
    return [[self topViewController] supportedInterfaceOrientations];
}
查看更多
甜甜的少女心
4楼-- · 2019-01-06 14:20

The answers here pointed me in the correct direction although I couldn't get it to work by just cut and pasting because I am using UINavigationControllers inside of a UITabBarController. So my version in AppDelegate.m looks something like this, which will work for UITabBarControllers, UINavigationControllers or UINavigationControllers within a UITabBarController. If you are using other custom containment controllers, you would need to add them here (which is kind of a bummer).

- (UIViewController*)terminalViewController:(UIViewController*)viewController
{
  if ([viewController isKindOfClass:[UITabBarController class]])
  {
    viewController = [(UITabBarController*)viewController selectedViewController];
    viewController = [self terminalViewController:viewController];
  }
  else if ([viewController isKindOfClass:[UINavigationController class]])
  {
    viewController = [[(UINavigationController*)viewController viewControllers] lastObject];
  }

  return viewController;
}

- (NSUInteger)application:(UIApplication *)application
supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
  NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
  UIViewController* viewController = [self terminalViewController:window.rootViewController];

  if (viewController)
    orientations = [viewController supportedInterfaceOrientations];

  return orientations;
}

Another key thing to note is that you must override supportedInterfaceOrientations in your UIViewController subclasses or it will default to what you specified in your Info.plist.

查看更多
看我几分像从前
5楼-- · 2019-01-06 14:22

One thing I've found is if you have an old application that is still doing

[window addSubView:viewcontroller.view];  //This is bad in so may ways but I see it all the time...

You will need to update that to:

[window setRootViewController:viewcontroller]; //since iOS 4

Once you do this the orientation should begin to work again.

查看更多
Luminary・发光体
6楼-- · 2019-01-06 14:22

Firstly in order to make your app work in only mode you should be returning UIInterfaceOrientationMaskLandscape. In case you want to keep only portrait mode, you are doing things correctly.

Just add the UISupportedInterfaceOrientations key in the Info.plist and assign the interface orientation values your app intends to keep.

Also, you should be returning false from shouldAutoRotate in case you want to avoid auto rotation totally. But I would suggest you to return true from here and specify the correct orientations in supportedInterfaceOrientations method.

查看更多
一纸荒年 Trace。
7楼-- · 2019-01-06 14:23

If your are using a UINavigationController as the root window controller, it will be its shouldAutorotate & supportedInterfaceOrientations which would be called.

Idem if you are using a UITabBarController, and so on.

So the thing to do is to subclass your navigation/tabbar controller and override its shouldAutorotate & supportedInterfaceOrientations methods.

查看更多
登录 后发表回答