【问题标题】:iOS 6 shouldAutorotate: is NOT being callediOS 6 shouldAutorotate: 没有被调用
【发布时间】:2012-10-08 04:20:01
【问题描述】:

我一直在互联网上寻找解决方案,但一无所获。我正在尝试使我的 iOS 5 应用程序与 iOS 6 兼容。我无法让方向的东西正常工作。我无法检测到何时将发生轮换。这是我正在尝试的代码:

- (BOOL)shouldAutorotate {
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

新的supportedInterfaceOrientation: 方法被调用得很好。但是, shouldAutorotate 方法不会触发。我需要在旋转时进行一些图像交换,但没有任何迹象表明旋转即将发生。

提前致谢。

【问题讨论】:

  • 这里有答案:stackoverflow.com/questions/12260261/… 看到它:D
  • @KarenAnne,该答案并不能解决首先没有调用“shouldAutorotate”的问题。此外,“shouldAutorotateToInterfaceOrientation”在 iOS 6 中已被弃用,因此不应将其视为未来的有效选项。

标签: iphone ios cocoa-touch rotation ios6


【解决方案1】:

查看您的应用启动时是否收到以下错误。

应用程序窗口在应用程序启动结束时应该有一个根视图控制器

如果是这样,修复它的方法是在 AppDelegate.m 文件中进行以下更改(尽管似乎有很多答案如何解决这个问题):

// Replace
[self.window addSubview:[navigationController view]];  //OLD

// With
[self.window setRootViewController:navigationController];  //NEW

之后应该正确调用shouldAutoRotate

【讨论】:

  • 我认为这应该被接受为正确答案。我之前遇到过同样的问题,但可以通过执行以下操作来解决它: self.window.rootViewController = navigationController; (与@user1672376 的回答相同)
  • 是的,我一直在努力调用 shouldAutoRotate 方法,但是一旦我更改了上面的代码,它就无法正常工作了。这是我一直在寻找的正确答案。
  • 太棒了..它节省了我的时间.. ;-)
  • 也解决了我的问题。应该选择 IMO 这个答案。
  • 正确,你的回答拯救了我的一天。
【解决方案2】:

当使用 UINavigationController 作为应用程序的基础时,我使用以下子类让我能够灵活地允许最顶层的子视图控制器决定旋转。

@interface RotationAwareNavigationController : UINavigationController

@end

@implementation RotationAwareNavigationController

-(NSUInteger)supportedInterfaceOrientations {
    UIViewController *top = self.topViewController;
    return top.supportedInterfaceOrientations;
}

-(BOOL)shouldAutorotate {
    UIViewController *top = self.topViewController;
    return [top shouldAutorotate];
}

@end

【讨论】:

  • 这是迄今为止最简单、最优雅的解决方案,它允许 NavigationController 中的每个 ViewController 拥有自己支持的界面方向。
  • 这确实是一个很棒的解决方案,只需稍加调整即可与 SplitViewControllers 一起使用。
  • 为了更清楚,创建这样一个子类,然后将其设置为故事板身份检查器中导航控制器的自定义类。
  • 很好的答案,谢谢! supportedInterfaceOrientations 的返回类型应从 NSUInteger 更改为 UIInterfaceOrientationMask 以删除警告。
  • 注意:要在 iPad 上运行,您需要选择退出多任务处理:
【解决方案3】:

该方法不是确定它的正确方法。正确的方法是willRotateToInterfaceOrientation:duration:

应该旋转到方向(与 shouldAutorotate 相对)方法已被弃用,并且从 iOS 6 开始将不再被调用,但无论如何它并不打算以您使用它的方式使用。

编辑 对反复的反对票的回应。请解释为什么使用我指出的方法不是(引用 OP)“轮换即将发生的迹象”。题目内容与题目不符。

【讨论】:

  • -(BOOL)shouldRotate 已经出现在 iOS 6 中,但是,它从未被调用过。如何让视图控制器现在只在某些时候旋转(例如,有一个锁定按钮来防止旋转)?
  • 我弄清楚了为什么我的 shouldAutorotate 没有在 iOS 6 中被调用。这是因为我的视图控制器是 UINavigationController 的子级,而且导航控制器似乎没有委托 -shouldAutorotate 方法到它的 topViewController 就像以前的行为一样。您可以通过继承 UINavigationController 并覆盖 -shouldAutorotate 和 -supportedIntervalOrientations 方法来解决此问题。
  • @possen 出于好奇,你为什么这么说?对我来说,一个类别似乎是一个陌生的选择,因为它会删除现有的实现并使其无法访问(将产生编译器警告)
  • Apple 论坛上有一个帖子,Apple 代表明确建议反对创建一个类别,但改为子类化。 devforums.apple.com/message/744384
  • 这个答案是完全错误的,shouldAutorate 没有被弃用,事实上它只在 IOS 6.0 上可用,它是确定屏幕是否应该旋转的正确方法。 willRotateToInterfaceOrientation:duration: yes 屏幕旋转时调用,不决定是否旋转。
【解决方案4】:

看起来在 iOS 6 上,容器导航控制器在旋转时不会参考子视图控制器:

iOS 6 release notes

现在,iOS 容器(如 UINavigationController)不咨询 他们的孩子来决定他们是否应该自动旋转。经过 默认,一个应用和一个视图控制器支持的接口 iPad 的方向设置为 UIInterfaceOrientationMaskAll iPhone 的 idiom 和 UIInterfaceOrientationMaskAllButUpsideDown 成语。

这种行为很容易测试。我所做的是使用相同的自定义视图控制器

  1. 作为主视图控制器的第一种情况
  2. 作为 UIPageViewController 的子级的第二种情况

在第一种情况下,一切都在自定义导航控制器中由shouldAutorotatesupportedInterfaceOrientations 的组合决定,因为supportedInterfaceOrientations 与应用程序支持的方向一致。

在第二种情况下,即使 UIPageViewController 调用了自定义视图控制器的supportedInterfaceOrientations,也不会考虑返回值。如果这两个方法在 UIPageViewController 的子类中被覆盖,它就会起作用。我不确定它的副作用,因为这个类不应该是子类。

【讨论】:

    【解决方案5】:

    如果您的viewControllerviewController 中的UINavigationController 的孩子,那么您可以执行以下操作:

    • 子类UINavigationController
    • 在您的子类中覆盖 shouldAutoRotate
    • 在调用此方法时发送您的 topViewController 此消息

    // 这个方法在你的UINavigationController 子类中

    - (BOOL)shouldAutorotate
    {
        if([self.topViewController respondsToSelector:@selector(shouldAutorotate)])
        {
            return [self.topViewController shouldAutorotate];
        }
        return NO;
    }
    
    • 现在您的 viewController 将分别响应此方法。
    • 请注意,您可以对其他 orinetaion-methods 执行相同操作

    【讨论】:

      【解决方案6】:

      当您的应用启动时,我也收到以下错误。

      “应用程序窗口在应用程序启动结束时应该有一个根视图控制器”

      我正在使用 UISplitViewController *splitViewController

      如果是这样,修复它的方法是在 AppDelegate.m 文件中进行以下更改:

      替换

       [self.window addSubview:[splitViewController view]];
      

      [self.window setRootViewController:splitViewController];
      

      在此shouldAutoRotate 被调用并正常工作之后。

      【讨论】:

        【解决方案7】:

        我使用的是 iOS 7,但我相信我的案例可能对其他人有所帮助。

        我有一个以 UITabBarController 为根的深层视图控制器层次结构。保证调用 shouldAutorotate 的唯一地方是在 UITabBarController 内部。所以我只是继承了 UITabBarController 并将我的旋转控制逻辑放在我的 shouldAutorotate 方法中。

        【讨论】:

          【解决方案8】:

          我会这样做

          如果您想检查当前方向,则将此行添加到您的 viewconrtoller.m 文件中

           #define isPortrait [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown
          

          然后你要检查方向的地方,写下如下的条件

          - (void)viewDidLoad
          {
          
                  if(isPortrait)
                  {
                      //portrait mode....
          
                      NSLog(@"its in IsPotraitMode");
                  }
                  else
                  {
                      //landscape mode....
                      NSLog(@"its in IsLandscapeMode");
                  }
          }
          

          【讨论】:

          • 不,viewDIDLoad 为时过早:VC 还不知道它的视图。当 self.view 知道其当前帧时,在 viewWillAppear 中执行此操作。
          【解决方案9】:

          如果您使用 UINavigationController 作为应用程序的基础。我创建了一个 UINavigationController 类别并将其命名为“UINavigationController+autoRotate”。 把它放在你的 UINavigationController+autoRotate.h 中:

          #import <UIKit/UIKit.h>
          
          @interface UINavigationController (autoRotate)
          
          -(BOOL)shouldAutorotate;
          -(NSUInteger)supportedInterfaceOrientations;
          
          @end
          

          把这个放到 UINavigationController+autoRotate.m:

          #import "UINavigationController+autoRotate.h"
          
          @implementation UINavigationController (autoRotate)
          
          - (BOOL)shouldAutorotate
          {
              return [self.visibleViewController shouldAutorotate];
          }
          
          - (NSUInteger)supportedInterfaceOrientations
          {
              return [self.topViewController supportedInterfaceOrientations];
          }
          
          @end
          

          【讨论】:

            猜你喜欢
            • 2013-12-05
            • 2012-10-01
            • 1970-01-01
            • 2014-05-20
            • 2011-10-03
            • 1970-01-01
            • 2011-08-27
            • 2014-12-10
            • 1970-01-01
            相关资源
            最近更新 更多