在 UIViewController 中管理方向的说明

Clarifications on managing orientations in UIViewController

我的配置如下:

UINavigationController
    -> ViewController

其中 ViewController 是导航控制器的根视图控制器。

ViewController 可以模态呈现另一个视图控制器,ModalViewController,如下所示。

self.presentViewController(modalViewController, animated: true, completion: nil)

ModalViewController 中,我覆盖了以下方法。模态视图控制器实际上只能在 Landscape 模式下呈现。

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return .Landscape
}

然后我覆盖 ViewController 响应方向变化的方法。

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)        
    print("Size is \(size)")
}

我注意到,如果显示模态视图控制器,仅当 ModalViewController 处于 Landscape 模式时,才会记录 ViewController 中的 print,而它未登录 Portrait。换句话说,当我旋转设备时,ModalViewController 应该只能显示 Landscape 方向。在引擎盖下,即使 ViewController 不可见(并且设备在 Portrait 中),此控制器也应该能够响应大小变化。事实并非如此,因为我看不到 print 日志。

用例:

如果 ModalViewController 不可见,这是打印日志

Size is (1024.0, 768.0)
Size is (768.0, 1024.0)
Size is (1024.0, 768.0)
Size is (768.0, 1024.0)

ModalViewController 模态呈现时

Size is (1024.0, 768.0)
Size is (1024.0, 768.0)

这是正确的行为吗?我的目标是响应 ViewController 的方向变化,即使(当 ModalViewController 打开时)设备处于纵向模式。有什么线索吗?

编辑

基于 matt 评论。

If ViewController is not the frontmost view controller it has no business "responding to orientation changes". You've merely stumbled across an implementation detail or edge case in which you should have no interest.

ViewController 是一个复杂的控制器,充当 parent 视图控制器。它有两个 children:PortraitViewControllerLandscapeViewController。这些控制器在 viewWillTransitionToSize 方法中交换。只要 ModalViewController 不可见(未显示),交换就会以正确的方式进行。相反,当出现 ModalViewController 时,交换仅针对 Landscape 模式运行(参见上面的日志)。

在我看来,你只是想在错误的时间做某事。当模式视图控制器被关闭并且您的视图控制器的视图即将重新出现时,您将收到大量警告(包括 appearlayout 事件)并且您可以根据当前方向,在您的视图对用户可见之前。