【问题标题】:Multiple Presented View Controllers and Rotation on iPadiPad 上显示的多个视图控制器和旋转
【发布时间】:2012-05-15 11:38:09
【问题描述】:

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

  1. 视图控制器“A”(根视图控制器)以“表单”模式呈现样式呈现模式视图控制器(称为“B”)。

  2. 视图控制器 B 以“全屏”模式呈现样式呈现视图控制器“C”。

  3. iPad 旋转,而视图控制器 C 是最顶端的视图控制器。

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

据我所知,链接多个呈现的视图控制器应该没有问题——事实上,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 的方向保存到 B 的回调中,然后在下一次调用 -shouldAutoRotateToInterfaceOrientation 时使用该信息,并仅在 C 被关闭时返回 YES。这修复了在未进行此检查的情况下出现的损坏 UI,但视图控制器 B 不会将其界面方向更新为该值,因此后续的模态演示将从设备的错误一侧进行动画输入/输出。

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

提前致谢。

【问题讨论】:

    标签: objective-c ios ipad modalviewcontroller


    【解决方案1】:

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

    模态表示实际上应该用于单个死端实体(单个视图控制器或包含多个子视图控制器的导航控制器)。

    出于兴趣,您是说这在 iPhone 上可以正常工作,但在 iPad 上不行?还是您在 iPhone 版本上不允许轮换?

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

    【讨论】:

    • 我同意使用导航控制器作为模态的根会减少混乱。但是,我尝试匹配的设计需要视图控制器 B 的表单样式,以及视图控制器 C 的全屏演示。这似乎是实现所需结果的阻力最小的路径,但不幸的是它似乎有一些不明显的问题。我实际上不确定iPhone上是否存在同样的问题——假设手机上禁用了旋转是正确的。
    【解决方案2】:

    我曾在 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 上的视图控制器上会如何表现。由于它支持具有不同模态呈现风格的视图控制器,因此可能会有一些惊喜。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多