UIControllers的选择性自转

时间:2009-11-23 10:07:29

标签: iphone cocoa-touch user-interface

我做了一些关于自转的实验。 情况:我有一个TabBar 4(标签),三个应该只是肖像。最后一个是UINavigationController,它本身不应该自动旋转任何堆叠的控制器。它基本上是一个浏览应用程序,因为我显示文件和文件夹一切都应该是肖像。有时候会推出一个特殊的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。基本上这是有效的,因为我有所有UIViewControllers回答NO,除了我上面描述的特定的一个:正确地,当旋转模拟器时,只有当特殊的UIViewController可见时,界面旋转到横向,这是完美的。这里的Tabbar是隐藏的,所以用户也不会得到那个旋转的(这在我的设计中是不一致的:基本上每当tabbar可见时,这意味着除了在这个特殊视图中的任何地方,应用程序只是纵向)。

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

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

我使用3.0的模拟器,dunno,如果这有所不同。

4 个答案:

答案 0 :(得分:1)

我知道这不是解决您问题的方法,但我认为在同一个UINavigationController上混合纵向纵向+横向或仅横向页面时,您应该真正避免使用这种用户界面。不幸的是,轮换管理非常错误,不同固件版本的错误也各不相同。

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

如果您仍想这样做,我建议您做以下事情:

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

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

问题在于您正在转动UITabBarController(子视图控制器位于其上),而不仅仅是子视图控制器。您应该能够在子视图控制器中实现shouldAutorotateToInterfaceOrientation: 并使其正常工作。它还可以简化您的代码。

我从未遇到过此问题,但我也从未在shouldAutorotateToInterfaceOrientation:UITabBarController这样的“容器”视图控制器中实现UINavigationController

答案 3 :(得分:0)

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