【问题标题】:Selective Autorotation of UIControllersUIControllers 的选择性自动旋转
【发布时间】:2009-11-23 10:07:28
【问题描述】:

我做了一些关于自转的实验。 情况:我有一个 TabBar 4(标签),三个应该是纵向的。最后一个是 UINavigationController,它本身不应该自动旋转任何堆叠的控制器。它基本上是一个浏览应用程序,因为我显示文件和文件夹,所以一切都应该是纵向的。有时,一个特殊的 UIViewController 被推送,我只希望这个 UIViewController 自动旋转(它总是堆栈中的最后一个)。在最后一个视图中,标签栏是隐藏的。

我是如何实现目标的:我将 UITabBarController 子类化,以覆盖标准的 shouldAutorotate 方法行为:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    if([self.selectedViewController isKindOfClass:[UINavigationController class]])
        return [[(UINavigationController*)self.selectedViewController visibleViewController] shouldAutorotateToInterfaceOrientation:interfaceOrientation];
    else
        return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];

这样,shouldAutorotate 的答案被转发到受控选项卡,特别是对于 UINavigationController,它再次被委托给可见的 UIViewController。基本上这是可行的,因为我所有的 UIViewController 都回答“否”,除了我上面描述的那个:正确地,当旋转模拟器时,只有当特殊的 UIViewController 可见时,界面才会旋转到横向,这是完美的。这里的 Tabbar 是隐藏的,所以用户也不会得到那个旋转的(这在我的设计中是不一致的:基本上只要 tabbar 可见,这意味着除了这个特殊视图之外的任何地方,应用程序都是纵向的)。

问题是我希望这样,即使设备仍处于横向模式并且用户弹出特殊的 ViewController,界面应该表现一致并返回纵向模式。相反,当我弹出时,界面保持在横向(它不是以这种方式设计的,所以它当然是一团糟),即使显示一个 UIViewController 会对 shouldAutorotate 回答 NO ......这是因为(我认为)方法是仅在发生旋转时调用,因此在实际再次发生旋转之前,界面无论如何都会旋转为横向。

如何避免这种情况?我的第一个解决方案是以某种方式拦截最后一个视图的弹出,并在弹出之前手动旋转视图......但我不确定,我希望有一些更强大的方法来处理!

我用的是3.0的模拟器,不知道有没有区别。

【问题讨论】:

  • 长话短说,您问是否有办法让环境在从堆栈中弹出视图控制器时重新评估 shouldAutorotate.. 方法?
  • 实际上,我只是希望用户始终在纵向模式下看到导航堆栈上的 n-1 个 UIViewController,即使他在横向模式下弹出最后一个(允许最后一个视图)。如果在弹出横向视图时重新评估 shouldAutorotate 会导致自动旋转回纵向,那么答案是肯定的

标签: iphone cocoa-touch user-interface


【解决方案1】:

我知道这不能解决您的问题,但我认为当仅纵向纵向+横向或仅横向页面混合在同一个 UINavigationController 上时,您应该真正避免这种用户界面。不幸的是,轮换管理存在极大的错误,并且错误因固件版本而异。

我在我的一个项目中设法完成了完全相同的事情,但后来由于固件错误而不得不将其删除:例如,如果您在横向模式下按下“返回”按钮并返回仅纵向视图,经常发生状态栏和/或导航栏保持横向模式并且布局完全破坏的情况。据我所知,虽然固件 2.x 中已经存在此错误,但尚未修复。

如果你仍然想这样做,我建议以下几点:

  1. 确保所有重写的 UIViewController 方法(init、viewWillAppear 等)都调用其 [super methodName]。如果没有,自动旋转是无声的错误。这在“为 iPhone OS 3.0 技术说明做好准备”(https://developer.apple.com/iphone/checklist/) 中已提及,但目前该文档不可用:(

  2. 您可以尝试在离开横向视图时调用未记录的 [UIDevice setOrientation:] 方法。有时需要调用两次,一次使用当前方向,一次使用所需方向:) 如果状态栏保持横向模式,您可能还需要调用 [UIDevice setStatusBarOrientation:]。但请注意,如果您使用这些方法,Apple 可能会拒绝您的应用程序(他们前段时间引入了一种自动工具,可以检测您的应用程序中是否存在未记录的符号)。

【讨论】:

    【解决方案2】:

    我和你有同样的问题,我是这样解决的: 我对UITabBarController 进行了子类化,并添加了以下代码:

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        if (self.selectedViewController)
            return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
        else
            return (interfaceOrientation == UIDeviceOrientationPortrait);
    }
    

    这样,每个子视图控制器都可以控制自己的方向。

    【讨论】:

      【解决方案3】:

      问题是您正在旋转UITabBarController(上面有子视图控制器),而不仅仅是子视图控制器。您应该能够在您的子视图控制器中实现shouldAutorotateToInterfaceOrientation: only 并让它正常工作。它还将简化您的代码。

      我从来没有遇到过这个问题,但我也从来没有在像UITabBarControllerUINavigationController 这样的“容器”视图控制器中实现shouldAutorotateToInterfaceOrientation:

      【讨论】:

      • 是的,你是对的......但是当我尝试仅在子视图控制器中设置自动旋转时,我想到了这一点,但这似乎不起作用。我开始只在最后一个视图控制器中覆盖 shouldAutorotate ......什么都没有::调用 shouldAutorotate(我使用 NSLogs 来查看),但从未调用过 willRotate。然后我扩展到所有堆叠的视图控制器,但没有再发生。然后我将 UINavigationController 本身子类化以允许自动旋转,但是没有......只有当我将 TabBar 子类化以允许自动旋转时,一切都开始旋转。
      • 奇怪:/。如果您有时间,您可以编写一个最小的重现案例并将其作为错误报告提交给 Apple。
      【解决方案4】:

      您的实现的问题是您使用 UINavigationController 的 visibleViewController 成员。您应该改用 topViewController,一切都会按预期工作。

      【讨论】:

        猜你喜欢
        • 2010-11-14
        • 1970-01-01
        • 1970-01-01
        • 2011-09-28
        • 1970-01-01
        • 1970-01-01
        • 2019-05-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多