iOS6:supportedInterfaceOrientations不工作(调用但接口仍然旋转)

时间:2012-09-16 14:10:24

标签: iphone objective-c ios ios6

在我的应用中,我有多个视图,一些视图需要同时支持纵向和横向,而其他视图只需要支持纵向。因此,在项目摘要中,我已经选择了所有方向。

以下代码用于在iOS 6之前禁用给定视图控制器上的横向模式:

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

由于在iOS6中弃用了shouldAutorotateToInterfaceOrientation,我已将上述内容替换为:

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

当视图出现时我会正确调用此方法(我可以设置断点以确保这一点),但是界面仍然会旋转到横向模式,而不管我是否只为纵向模式返回蒙版。我做错了什么?

目前似乎无法构建每个视图具有不同方向要求的应用。它似乎只遵循项目摘要中指定的方向。

15 个答案:

答案 0 :(得分:69)

如果您使用 UINavigationController作为根窗口控制器,它将 shouldAutorotate& supportedInterfaceOrientations将会被召唤。

如果您使用的是 UITabBarController ,请注意等等。

所以要做的是将您的导航/标签栏控制器子类化并覆盖其shouldAutorotate& supportedInterfaceOrientations方法。

答案 1 :(得分:30)

尝试在AppDelegate.m中更改此代码

//   self.window.rootViewController = self.navigationController;

    [window setRootViewController:navigationController];

这是完整的答案

shouldAutorotateToInterfaceOrientation not being called in iOS 6

XD

答案 2 :(得分:20)

在我的情况下,我有UINavigationController和我的视图控制器。我不得不继承UINavigationController,为了只支持Portrait,添加这个方法:

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

所以在UINavigationController子类中,我需要检查当前topViewController支持哪个方向。

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

答案 3 :(得分:15)

我发现有一件事是你有一个旧的应用程序还在做什么

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

您需要将其更新为:

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

一旦你这样做,方向应该开始重新开始。

答案 4 :(得分:14)

对于iOS6,最好的方法是在Ray Wenderlich团队的“iOS6 By Tutorials”中注明 - http://www.raywenderlich.com/并且在大多数情况下都比为UINavigationController创建子类更好。

我正在使用带有故事板的iOS6,其中包含一个UINavigationController设置为初始视图控制器。

// AppDelegate.m - 不幸的是,此方法在iOS6之前不可用

- (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 - 返回你想为每个UIViewController支持的方向

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

答案 5 :(得分:10)

正如其他人所说,如果您正在使用UINavigationController并且想要自定义各种视图,那么您需要将UINavigationController子类化,并确保您拥有这两个组件:

@implementation CustomNavigationController

// -------------------------------------------------------------------------------
//  supportedInterfaceOrientations:
//  Overridden to return the supportedInterfaceOrientations of the view controller
//  at the top of the navigation stack.
//  By default, UIViewController (and thus, UINavigationController) always returns
//  UIInterfaceOrientationMaskAllButUpsideDown when the app is run on an iPhone.
// -------------------------------------------------------------------------------
- (NSUInteger)supportedInterfaceOrientations
{
    return [self.topViewController supportedInterfaceOrientations]; 
}

// -------------------------------------------------------------------------------
//  shouldAutorotate
//  Overridden to return the shouldAutorotate value of the view controller
//  at the top of the navigation stack.
//  By default, UIViewController (and thus, UINavigationController) always returns
//  YES when the app is run on an iPhone.
// -------------------------------------------------------------------------------
- (BOOL)shouldAutorotate
{
    return [self.topViewController shouldAutorotate];
}

然后,在任何只有肖像的视图中,您将包括:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

并且在任何观点中都是颠倒过来的一切:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

答案 6 :(得分:2)

基本上如上所述,但更详细:

  1. 创建一个新文件,该文件是UINavigationController
  2. 的子类
  3. 转到故事板,然后单击导航控制器,将其类设置为刚创建的类<​​/ li>
  4. 在此类(.m文件)中添加以下代码,使其保持纵向模式:

    (BOOL)shouldAutorotate
    {
      return NO;
    } 
    
    (NSUInteger)supportedInterfaceOrientations
    {
     return UIInterfaceOrientationMaskPortrait;
    }
    
  5. 这对我有用

答案 7 :(得分:1)

此代码对我有用:

-(BOOL)shouldAutorotate {
     return YES;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAll;
}

iPhone/iPad App Orientation查看我自己的答案

答案 8 :(得分:1)

我认为最好的方法是做一个类别而不是子类化UINavigationControllerUITabbarController

您的UINavigationController + Rotation.h

#import <UIKit/UIKit.h>

@interface UINavigationController (Rotation)

@end

您的UINavigationController + Rotation.m

#import "UINavigationController+Rotation.h"

@implementation UINavigationController (Rotation)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}


@end

尝试让所有控制器导入此类别,这就像魅力一样。 您甚至可以使控制器不旋转并按下另一个将旋转的控制器。

答案 9 :(得分:0)

尝试添加shouldAutorotate方法

答案 10 :(得分:0)

首先,为了让您的应用仅以模式运行,您应该返回UIInterfaceOrientationMaskLandscape。如果你想只保留肖像模式,你就是在正确地做事。

只需在Info.plist中添加UISupportedInterfaceOrientations键,然后指定应用程序打算保留的界面方向值。

另外,如果你想完全避免自动轮换,你应该从shouldAutoRotate返回false。但我建议你从这里返回true并在supportedInterfaceOrientations方法中指定正确的方向。

答案 11 :(得分:0)

我和你有同样的情况。我知道你已经接受了答案,但我想我还要加一个答案。这是我理解新版旋转系统的工作方式。根视图控制器是唯一可以调用的视图控制器。我认为,推理的原因在于,对于子视图控制器来说,旋转视图通常没有意义,因为它们只会保留在根视图控制器的框架内。

那么,会发生什么。首先shouldAutorotate在根视图控制器上称为 。如果返回NO,那么一切都会停止。如果返回YES,则调用supportedInterfaceOrientations方法。如果在此方法中确认了界面方向来自Info.plist或应用程序委托的全局支持方向,则视图将旋转。在轮换之前,查询shouldAutomaticallyForwardRotationMethods方法。如果YES(默认值),那么所有孩子都会收到willdidRotateTo...方法以及父级(他们会将其转发给孩子)。

我的解决方案(直到有一个更有说服力的解决方案)是在supportedInterfaceOrientations方法期间查询最后一个子视图控制器并返回其值。这让我可以旋转一些区域,同时只保留其他区域。我意识到它很脆弱,但是我没有看到另外一种不涉及事件调用,回调等问题的方法。

答案 12 :(得分:0)

如果您使用UINavigationController,则必须在shouldAutorotate的子类中实施supportedInterfaceOrientationsUINavigationController

如果shouldAutorotate返回YES然后生效supportedInterfaceOrientations,则可以通过两个步骤进行控制。这是一个非常好的组合。

这个例子,除了CoverFlowView和PreviewView之外,我的大多数视图都是Portrait。 CoverFlowView传输到PreviewView,PreviewView想要跟随CoverFlowCView的旋转。

@implementation MyNavigationController

-(BOOL)shouldAutorotate
{

if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"PreviewView")])

return NO;

else

return YES;

}



-(NSUInteger)supportedInterfaceOrientations

{

if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromString(@"CoverFlowView")])

return UIInterfaceOrientationMaskAllButUpsideDown;

else

return UIInterfaceOrientationMaskPortrait;

}

...

@end

答案 13 :(得分:0)

我的解决方案:子类UINavigationController并将其设置为window.rootViewController

层次结构的顶层视图控制器将控制方向,一些代码示例: subclassed UINavigationController

答案 14 :(得分:0)

这里的答案指出了我正确的方向,虽然我不能通过剪切和粘贴来使它工作,因为我在UITabBarController中使用UINavigationControllers。所以我在AppDelegate.m中的版本看起来像这样,它适用于UITabBarController中的UITabBarControllers,UINavigationControllers或UINavigationControllers。如果您正在使用其他自定义收容控制器,则需要在此处添加它们(这有点令人失望)。

- (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;
}

另一个需要注意的关键是你必须覆盖UIViewController子类中的supportedInterfaceOrientations,否则它将默认为你在Info.plist中指定的内容。