多个呈现的视图控制器和iPad上的旋转

时间:2012-05-06 20:29:45

标签: objective-c ios ipad modalviewcontroller

我最近在将一些代码从iPhone应用程序移植到iPad时遇到了问题。它可能与here所描述的问题有关,但我发现该问题的解释/解决方案并不令人满意。场景是这样的:

  1. 查看控制器'A'(根视图控制器)使用“表单”模式演示样式显示模态视图控制器(称为'B')。

  2. 视图控制器B使用“全屏”模式演示样式显示视图控制器“C”。

  3. 当视图控制器C是最顶级的视图控制器时,iPad会旋转。

  4. 解雇C后,B会重新显示,但方向不正确。

  5. 据我所知,链接多个呈现的视图控制器不应该存在问题 - 实际上,Presenting View Controllers from Other View Controllers文档中明确支持此行为。我还在iOS 5 Release Notes中阅读了以下声明:

      

    iOS 5中的旋转回调不适用于通过全屏显示的视图控制器。这意味着如果您的代码在另一个视图控制器上呈现视图控制器,然后用户随后将设备旋转到不同的方向,则在解雇时,底层控制器(即呈现控制器)将不会接收任何旋转回调。但请注意,呈现控制器在重新显示时将接收viewWillLayoutSubviews调用,并且可以从此方法查询interfaceOrientation属性并用于正确布局控制器。

    据我所知,这不会发生 - 视图控制器B接收到对-shouldAutoRotateToInterfaceOrientation的调用,但此调用中interfaceOrientation参数的值是视图控制器B在呈现视图控制器C时的界面方向的值,不是解雇时C的界面取向的价值。由于我们在iPad上,所有这些视图控制器都在-shouldAutoRotateToInterfaceOrientation中返回YES。因此B视图的界限永远不会改变,所以-willLayoutSubviews永远不会被调用。

    我已经尝试在B解除之前将视图控制器C的方向保存在回调中,然后在下次使用该信息时调用theAouldAutoRotateToInterfaceOrientation,并且仅在C被解除时返回Y的方向。这修复了,在没有进行此检查的情况下出现的损坏的UI,但是视图控制器B没有将其界面方向更新为此值,因此后续的模态演示将从设备的错误侧进行动画制作。

    有没有人能够成功获得像这样的视图控制器配置?这似乎并不像一个场景那么不寻常,所以我有点惊讶它没有像我最初预期的那样工作。

    提前致谢。

2 个答案:

答案 0 :(得分:0)

在我看来,如果您不使用导航控制器,多个链式模态视图控制器会导致令人困惑和恼人的用户体验。我认为View控制器B应该在导航控制器中(如果你不想要,你不必显示nab栏)。

模态演示实际上应该是针对单个死胡同的实体(单个视图控制器或包含多个子视图控制器的导航控制器)。

出于兴趣,您是说这在iPhone上运行良好但在iPad上运行不正常吗?或者你不允许在iPhone版本上轮换?

我还发现this thread表示从根视图控制器呈现模态视图控制器可能会有所帮助。

答案 1 :(得分:0)

我曾在iPhone上展示多个模态视图控制器。布局没有问题,除非我自己的代码处理多个方向有问题。当视图控制器在另一个视图控制器后面时,实际上永远不会调用自动旋转方法,所以我也会调整viewWillAppear上的布局:

在viewWillAppear:,willRotateToInterfaceOrientation:duration:和didRotateToInterfaceOrientation :,我会根据需要将布局调整到正确的方向,例如:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self switchToInterfaceOrientation:self.interfaceOrientation];
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willRotateToInterfaceOrientation:interfaceOrientation duration:duration];
    [self switchToInterfaceOrientation:toInterfaceOrientation];
    // be careful, self.view.frame is still according to self.interfaceOrientation
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
    // self.view.frame is updated
    // update something else here
}

- (void)switchToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // update your layout here
}

我不确定上述代码在iPad上的视图控制器上的行为方式。由于它支持具有不同模态呈现样式的视图控制器,因此可能会有一些惊喜。