当我推送具有不同支持方向的控制器时,为什么 UINavigationController 不改变方向?

Vad*_*ick 2 orientation uiviewcontroller uinavigationcontroller uiinterfaceorientation

我的代码是如何设置的:

我使用导航控制器,带有控制方向的委托:

class NavDelegate: UINavigationControllerDelegate {
  func navigationControllerSupportedInterfaceOrientations(_ navigationController: UINavigationController) -> UIInterfaceOrientationMask {
    print("Checking orientation")
    if topViewController != nil {
      return topViewController!.supportedInterfaceOrientations
    }
    return .portrait
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

我的应用程序的主视图控制器名为 MainController,它仅限纵向:

class MainController: UIViewController {
  override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

我有另一个控制器 PhotoController,它支持所有四个方向:

class PhotoController: UIViewController {
  override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .all
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

我使用 pushViewController() 将 PhotoController 推到 MainController 之上。

问题:

每个控制器本身都能正确处理方向——当我将手机旋转到所有四个方向时 MainController 保持纵向,而 PhotoController 旋转到所有四个方向。

但是这种情况不能正常工作:

  1. 将手机横放,主控制器在屏幕上。
  2. 控制器处于肖像状态(如预期)。
  3. 将 PhotoController 推入堆栈。

我希望 PhotoController 根据设备方向以横向打开,但它仍然以纵向打开。如果我手动来回旋转手机,控制器会随着手机旋转。显然,用户不应该这样做,来回旋转手机来让控制器旋转。

当我点击 MainController 中推动 PhotoController 的按钮时,不会调用 navigationControllerSupportedInterfaceOrientations()。

我还尝试了什么:

  • 覆盖 shouldAutorotate 以在 PhotoController 中返回 true。
  • ...并在主控制器中。
  • 覆盖 UINavigationController 中的 supportedInterfaceOrientations 而不是使用委托。
  • 检查 UINavigationController.visibleViewController 而不是 .topViewController。这不起作用,因为 topviewController 原来是一个 iOS 私有类 UISnapshotModalViewController,而不是我的类,所以在它上面调用 supportedInterfaceOrientation() 大概不会返回正确的值。

这些都不起作用。

Vad*_*ick 5

解决方案原来是调用 UIViewController。在 viewWillAppear() 或 viewDidAppear() 中尝试 RotationToDeviceOrientation()。

在前一种情况下,推动控制器的动画与设备旋转动画同时发生,看起来很奇怪。在后一种情况下,旋转发生在控制器过渡动画完成之后。这看起来也很奇怪,虽然方式不同。