如何从 AppDelegate 中的 supportedInterfaceOrientationsFor 方法获取调用 ViewController?

How can I get the calling ViewController from the supportedInterfaceOrientationsFor method in AppDelegate?

我在 Swift 4 中的应用程序中添加了一项功能,它允许视图在显示图表时定向为横向或纵向。我为每个方向创建了两个单独的视图,并创建了处理该过程的逻辑。它工作正常,除了一个小问题,如果我能确定调用 ViewController,我可以解决这个问题。我试过使用

self.window?.rootViewController?.presentedViewController

这并没有被证明是准确的。我已经检查了应用程序和 window 的参数,但没有成功。这是可能的还是我需要依赖全局变量?

应用程序委托 return 是一个位掩码,指示整个应用程序支持的 "maximum set" 方向,无论当前显示的是哪个视图控制器。

此外,还询问了所呈现的具体视图控制器 (supportedInterfaceOrientations) 并且 return 它自己支持的方向。

最后,两个 return 值将相交得到当前支持的方向。

如果我没记错的话,两个值必须至少在一个方向上一致。如果例如app delegate 说它只支持 "portrait (up)",但是 view controller 只支持 "landscape left",你的应用会崩溃(或者做一些更糟糕的事情)

您可以像这样检索应用程序的最顶层 viewController:

func topViewController() -> UIViewController {
        let controller = UIApplication.shared.keyWindow?.rootViewController
        if let presentedVC = controller?.presentedViewController {
            return presentedVC
        }
        return controller!
    }

登顶ViewController 取决于视图的配置。使用 .isKind(of: VC) 可以帮助您 return 根据您可能使用的任何视图层次结构 ViewController 适当的 ViewController:

private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? {
    if (rootViewController == nil) { return nil }
    if (rootViewController.isKind(of: UITabBarController.self)) {
        return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UITabBarController).selectedViewController)
    } else if (rootViewController.isKind(of: UINavigationController.self)) {
        return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UINavigationController).visibleViewController)
    } else if (rootViewController.presentedViewController != nil) {
        return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController)
    }
    return rootViewController
}