【问题标题】:Autorotate in iOS 6 has strange behaviouriOS 6 中的自动旋转有奇怪的行为
【发布时间】:2012-09-13 14:41:23
【问题描述】:

我有UITabBarController 应用程序,它可以播放视频并在其他UITabBar 选项卡中显示其他信息。在 iOS 6 中 UIView 旋转方法已被弃用,现在我需要使用 shouldAutoRotatesupportedInterfaceOrientations 方法。对于视频播放,我使用MPMoviePlayerViewController

如何只旋转这个播放器视图?我只能旋转整个应用程序,但不想这样做。我介绍了MPMoviePlayerViewController,但它不像在 iOS 5 和更早版本中那样旋转。

plist 设置中,我只设置了 1 个纵向界面方向。如果我设置其他 - 整个应用程序将被旋转。

【问题讨论】:

    标签: iphone objective-c ios mpmovieplayercontroller ios6


    【解决方案1】:

    来自 Apple 的 iOS 6 SDK 发行说明:

    自动旋转在 iOS 6 中发生了变化。在 iOS 6 中, UIViewController 的 shouldAutorotateToInterfaceOrientation: 方法已弃用。取而代之的是,您应该使用 supportedInterfaceOrientationsForWindow: 和 shouldAutorotate 方法。

    更多的责任正在转移到应用和应用代理身上。现在,iOS 容器(例如 UINavigationController)不会咨询它们的子容器来确定它们是否应该自动旋转。 默认情况下,应用程序和视图控制器支持的界面方向设置为 iPad 惯用语的 UIInterfaceOrientationMaskAll 和 iPhone 惯用语的 UIInterfaceOrientationMaskAllButUpsideDown。

    视图控制器支持的界面方向会随着时间而改变——即使是应用支持的界面方向也会随着时间而改变。 每当设备旋转或以全屏模式呈现样式呈现视图控制器时,系统都会向最顶层的全屏视图控制器(通常是根视图控制器)询问其支持的界面方向。 此外,仅当此视图控制器从其 shouldAutorotate 方法返回 YES 时,才会检索支持的方向。 系统将视图控制器支持的方向与应用支持的方向(由 Info.plist 文件或应用代理的 application:supportedInterfaceOrientationsForWindow: 方法确定)相交以确定是否旋转。

    系统通过将应用程序的supportedInterfaceOrientationsForWindow: 方法返回的值与最顶部全屏控制器的supportedInterfaceOrientations 方法返回的值相交来确定是否支持方向。 setStatusBarOrientation:animated: 方法并未完全弃用。它现在仅在最顶层全屏视图控制器的 supportedInterfaceOrientations 方法返回 0 时才有效。这使得调用者负责确保状态栏方向一致。

    为了兼容性,仍然实现 shouldAutorotateToInterfaceOrientation: 方法的视图控制器不会获得新的自动旋转行为。 (换句话说,它们不会回退到使用应用程序、应用程序委托或 Info.plist 文件来确定支持的方向。)相反,shouldAutorotateToInterfaceOrientation: 方法用于合成将由 supportedInterfaceOrientations 方法返回的信息.

    如果您希望整个应用旋转,那么您应该将 Info.plist 设置为支持所有方向。现在,如果您希望特定视图仅是纵向的,则必须执行某种子类并覆盖自动旋转方法以仅返回纵向。我这里有一个例子:

    https://stackoverflow.com/a/12522119/1575017

    【讨论】:

    • 您还可以指定每个设备的方向。即允许在 iPad 上进行特定旋转,但保持 iPhone 方向锁定。
    【解决方案2】:

    哎呀!用了半天,问题解决了!呵呵。

    正如上面的文档所说,就是这样!核心点是:

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

    所以,每当根控制器发生变化时,系统都会询问应用委托“那么,我们是什么?旋转与否?”

    如果“旋转”:

    仅当此视图控制器从其 shouldAutorotate 方法返回 YES 时才会检索支持的方向

    然后系统要求我们的应用委托

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

    这真的很简单。

    如何确定何时允许纵向或横向等 - 取决于您。由于某些原因,对根控制器的测试对我不起作用,但这有效:

    - (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {    
    
        return self.fullScreenVideoIsPlaying ?
            UIInterfaceOrientationMaskAllButUpsideDown :
            UIInterfaceOrientationMaskPortrait;
    }
    

    “fullScreenVideoIsPlaying”属性由我在需要时手动设置。

    唯一需要注意的重要事情是枚举。正如它在文档中所说的那样......(仔细阅读 iPad/iPhone 上面的内容)。因此,您可以根据需要使用它们。

    另一个小问题是关闭播放器控制器后的一些错误行为。曾经有一次它没有改变方向,但这种情况发生了一次,而且以某种奇怪的方式发生,而且只在模拟器中(当然仅限 iOS 6)。所以我什至无法做出反应,因为它出乎意料地发生了,在我的应用程序的其他一些元素上快速单击后,它旋转到正常方向。所以,不确定 - 可能是模拟器工作的一些延迟或什么(或者,真的是一个错误:))。

    祝你好运!

    【讨论】:

    • 哦!只是忘记了。相对于方向,我没有更改我的 plist 中的任何内容!我那里只允许放一张肖像!
    • 嗨!我做了完全相同的事情,但不同的是,在关闭横向视图控制器后它不会将方向更改回纵向模式......我可能忘记了什么吗?您有可以提供的简单示例项目吗?
    • 对不起,还没有看到关于评论的通知...我没有单独的代码,但看起来你确实漏掉了一些小东西。你也实现了这个方法吗?:- (BOOL)shouldAutorotate 因为正如文档所说:“此外,只有当这个视图控制器从它的 shouldAutorotate 方法返回 YES 时,才会检索支持的方向。"
    • 优秀的解决方案。 self.fullScreenVideoIsPlaying 检测它是否应该旋转是为我解决这个问题的方法。
    【解决方案3】:

    我的应用遇到了同样的问题。

    iOS 6 中的旋转是如何工作的。

    => 当你使用 UINavigationCONtroller 中的 AppDelegate 方法时

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

    决定是否旋转。

    => 当视图以 Modal 呈现方式呈现时的方法

    - (BOOL)shouldAutorotate
    

    位于该视图的 viewController 内会触发 appDelegate 中的方法。作为第一种情况,appDelegate 决定是否轮换。

    我的解决方案::

    我为 Modal 演示所做的就是这样。在应用委托中创建了一个标志。

    当标志为 YES 时,它会旋转为横向,否则它会旋转为唯一的纵向。

    - (NSUInteger)application:(UIApplication*)application
    supportedInterfaceOrientationsForWindow:(UIWindow*)window
    {
        if(self.shouldRotate ) //shouldRotate is my flag
        {
            self.shouldRotate = NO;
            return (UIInterfaceOrientationMaskAll);
        }
        return (UIInterfaceOrientationMaskPortrait);
    }
    

    并在旋转之间切换

    - (BOOL)shouldAutorotate
    {
        YourAppDelegate *mainDelegate = (YourAppDelegate*)[[UIApplication sharedApplication]delegate];
        mainDelegate.shouldRotate = YES;
    
        return YES;
    }
    

    注意:这仅适用于模型呈现的视图。 使用 Flag,不是一个好的编码习惯。

    【讨论】:

    • 并确保在关闭模态视图控制器时,设置 shouldRotate = NO;再次
    • 使用标志不被认为是最佳实践,但它是一个非常好的工作解决方案。
    【解决方案4】:

    您还可以继承 UITabBarController 以使其向其子级询问 shouldAutorotate 和 supportedInterfaceOrientation,如下所示:

    @implementation MyTabBarController
    
    -(BOOL)shouldAutorotate
    {
        return [self.selectedViewController shouldAutorotate];
    }
    
    -(NSUInteger)supportedInterfaceOrientations
    {
        return [self.selectedViewController supportedInterfaceOrientations];
    }
    
    @end
    

    然后您只需使用自定义容器代替标准容器即可!刚刚测试过。

    【讨论】:

      【解决方案5】:

      不幸的是,您需要打开 plist 中的所有方向,并在您不想旋转的所有视图控制器上使用 supportedInterfaceOrientations。 (在您的情况下,除了视频播放器之外的所有内容。)

      【讨论】:

      • 这有点正确(它确实对我有用)...但是从阅读fostah.com/ios/2012/09/27/ios6-orientation-handling.html 可以清楚地看出(例如)您可以将 plist 保留为仅支持肖像,然后实施应用程序委托中的 supportedInterfaceOrientationsForWindow 方法。就我而言,我有一个需要所有方向的电影播放器​​视图,但应用程序的其余部分是纵向的。
      【解决方案6】:

      试试这个,

      如果 TabBarController 是窗口的 RootViewController, 然后创建继承 TabBarController 的自定义类说 CustomTabBarController.h

      在CustomTabBarController.h中添加Below方法

      -(NSUInteger)supportedInterfaceOrientations // Must return Orientation Mask
      

      最后在 AppDelegate.m 中调用下面

      - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window  {
         if( [self.window.rootViewController supportedInterfaceOrientations]!=0) 
           {
              return [self.window.rootViewController supportedInterfaceOrientations];
          }
          return UIInterfaceOrientationMaskAll;
      }
      

      【讨论】:

        【解决方案7】:

        我发现设置它的最简单方法是使用“支持的界面方向”按钮 目标....摘要选项卡(在 iPhone/iPad 部署信息下)。

        它基本上是一个用于设置 plist 文件的 GUI

        【讨论】:

        • 是的。我发现这是解决在 ios 6 上开发的 ios5 开发应用程序的轮换问题的最快方法。我可能应该更冗长一些。谢谢
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多