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

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

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

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


当前回答

基于上面的Bob -c:

斯威夫特3.0

extension UIWindow {


    func visibleViewController() -> UIViewController? {
        if let rootViewController: UIViewController  = self.rootViewController {
            return UIWindow.getVisibleViewControllerFrom(vc: rootViewController)
        }
        return nil
    }

    class func getVisibleViewControllerFrom(vc:UIViewController) -> UIViewController {

        if vc.isKind(of: UINavigationController.self) {

            let navigationController = vc as! UINavigationController
            return UIWindow.getVisibleViewControllerFrom( vc: navigationController.visibleViewController!)

        } else if vc.isKind(of: UITabBarController.self) {

            let tabBarController = vc as! UITabBarController
            return UIWindow.getVisibleViewControllerFrom(vc: tabBarController.selectedViewController!)

        } else {

            if let presentedViewController = vc.presentedViewController {

                return UIWindow.getVisibleViewControllerFrom(vc: presentedViewController)

            } else {

                return vc;
            }
        }
    }
}

其他回答

presentViewController显示一个视图控制器。它不会返回一个视图控制器。如果你不使用UINavigationController,你可能正在寻找presenttedviewcontroller,你需要从根开始,向下迭代所呈现的视图。

if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }

    // topController should now be your topmost view controller
}

对于Swift 3+:

if var topController = UIApplication.shared.keyWindow?.rootViewController {
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }

    // topController should now be your topmost view controller
}

适用于iOS 13+

let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first

if var topController = keyWindow?.rootViewController {
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }

// topController should now be your topmost view controller
}

试试这个

let topVisibleVC = UIApplication.shared.keyWindow?.rootViewController?.visibleViewController

在Swift 3中找到可见的viewController

if let viewControllers = window?.rootViewController?.childViewControllers {

     let prefs = UserDefaults.standard

     if viewControllers[viewControllers.count - 1] is ABCController{
        print("[ABCController] is visible")

     }
}

这段代码找到最后添加的或最后可见的活动控制器。

我已经在AppDelegate中使用它来查找活动视图控制器

太多口味了,但都不是一种反复精心制作的。结合前面的内容:

     func topMostController() -> UIViewController? {
        var from = UIApplication.shared.keyWindow?.rootViewController
        while (from != nil) {
            if let to = (from as? UITabBarController)?.selectedViewController {
                from = to
            } else if let to = (from as? UINavigationController)?.visibleViewController {
                from = to
            } else if let to = from?.presentedViewController {
                from = to
            } else {
                break
            }
        }
        return from
    }

对于Swift 5+, iOS 13 +

extension UIViewController {
    static func topMostViewController() -> UIViewController? {
        if #available(iOS 13.0, *) {
            let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
            return keyWindow?.rootViewController?.topMostViewController()
        }
        
        return UIApplication.shared.keyWindow?.rootViewController?.topMostViewController()
    }
    
    func topMostViewController() -> UIViewController? {
        if let navigationController = self as? UINavigationController {
            return navigationController.topViewController?.topMostViewController()
        }
        else if let tabBarController = self as? UITabBarController {
            if let selectedViewController = tabBarController.selectedViewController {
                return selectedViewController.topMostViewController()
            }
            return tabBarController.topMostViewController()
        }
            
        else if let presentedViewController = self.presentedViewController {
            return presentedViewController.topMostViewController()
        }
        
        else {
            return self
        }
    }
}

用法:

当你在没有UIViewController实例的情况下获取topMostViewController时

guard let viewController = UIViewController.topMostViewController() else { return }
print(viewController)

当你获取UIViewController实例的topMostViewController时

let yourVC = UIViewController()
guard let vc = yourVC.topMostViewController() else { return }
print(vc)