如果没有UINavigationController,我似乎无法得到最顶端的UIViewController。以下是我目前所掌握的:

UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(vc, animated: true, completion: nil)

然而,它似乎没有做任何事情。keyWindow和rootViewController似乎也不是nil值,所以可选的链接应该不是问题。

注意:这样做不是一个好主意。它打破了MVC模式。


当前回答

对于swift 4 / 5 +获取topmost viewController

// MARK: UIApplication extensions

extension UIApplication {

    class func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {

        if let nav = base as? UINavigationController {
            return getTopViewController(base: nav.visibleViewController)

        } else if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
            return getTopViewController(base: selected)

        } else if let presented = base?.presentedViewController {
            return getTopViewController(base: presented)
        }
        return base
    }
}

如何使用

if let topVC = UIApplication.getTopViewController() {
   topVC.view.addSubview(forgotPwdView)
}

其他回答

对于任何寻求快速5/iOS 13+解决方案的人(keywindow自iOS 13以来已弃用)

extension UIApplication {

    class func getTopMostViewController() -> UIViewController? {
        let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
        if var topController = keyWindow?.rootViewController {
            while let presentedViewController = topController.presentedViewController {
                topController = presentedViewController
            }
            return topController
        } else {
            return nil
        }
    }
}

在一个非常罕见的情况下,使用自定义segue,最顶层的视图控制器不在导航堆栈或选项卡栏控制器中或被呈现,但它的视图被插入到关键窗口子视图的顶部。

在这种情况下,有必要检查UIApplication.shared.keyWindow.subviews.last == self。视图来确定当前视图控制器是否是最顶端的。

你把密码放哪了?

我在我的演示中尝试了你的代码,我发现,如果你把代码放进去

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 

将失败,因为关键窗口已经设置。

但我把你的代码放到了视图控制器中

override func viewDidLoad() {

它就是有用。

最简单的方法是从视图控制器堆栈中取出最后一个:

if let viewController: UIViewController = navigationController.viewControllers.last {
    // This `viewController` is on the top.
}
  var topViewController: UIViewController? {
        guard var topViewController = UIApplication.shared.keyWindow?.rootViewController else { return nil }
        while let presentedViewController = topViewController.presentedViewController {
            topViewController = presentedViewController
        }
        return topViewController
    }