Get top most UIViewController

后端 未结 24 1873
别那么骄傲
别那么骄傲 2020-11-22 14:47

I can\'t seem to get the top most UIViewController without access to a UINavigationController. Here is what I have so far:

UIApplic         


        
相关标签:
24条回答
  • 2020-11-22 15:20

    Slight Variation on @AlberZou using a computed variable rather than a function

    extension UIViewController {
      var topMostViewController : UIViewController {
    
        if let presented = self.presentedViewController {
          return presented.topMostViewController
        }
    
        if let navigation = self as? UINavigationController {
          return navigation.visibleViewController?.topMostViewController ?? navigation
        }
    
        if let tab = self as? UITabBarController {
          return tab.selectedViewController?.topMostViewController ?? tab
        }
    
        return self
      }
    }
    
    extension UIApplication {
      var topMostViewController : UIViewController? {
        return self.keyWindow?.rootViewController?.topMostViewController
      }
    }
    

    Then say

    if let topViewControler = UIApplication.shared.topMostViewController {
        ... do stuff
    }
    
    0 讨论(0)
  • 2020-11-22 15:22
    extension UIViewController {
        func topMostViewController() -> UIViewController {
            if self.presentedViewController == nil {
                return self
            }
            if let navigation = self.presentedViewController as? UINavigationController {
                return navigation.visibleViewController.topMostViewController()
            }
            if let tab = self.presentedViewController as? UITabBarController {
                if let selectedTab = tab.selectedViewController {
                    return selectedTab.topMostViewController()
                }
                return tab.topMostViewController()
            }
            return self.presentedViewController!.topMostViewController()
        }
    }
    
    extension UIApplication {
        func topMostViewController() -> UIViewController? {
            return self.keyWindow?.rootViewController?.topMostViewController()
        }
    }
    
    0 讨论(0)
  • 2020-11-22 15:23
      var topViewController: UIViewController? {
            guard var topViewController = UIApplication.shared.keyWindow?.rootViewController else { return nil }
            while let presentedViewController = topViewController.presentedViewController {
                topViewController = presentedViewController
            }
            return topViewController
        }
    
    0 讨论(0)
  • 2020-11-22 15:24

    The best solution for me is an extension with a function. Create a swift file with this extension

    First is the UIWindow extension:

    public extension UIWindow {
        var visibleViewController: UIViewController? {
            return UIWindow.visibleVC(vc: self.rootViewController)
        }
    
        static func visibleVC(vc: UIViewController?) -> UIViewController? {
            if let navigationViewController = vc as? UINavigationController {
                return UIWindow.visibleVC(vc: navigationViewController.visibleViewController)
            } else if let tabBarVC = vc as? UITabBarController {
                return UIWindow.visibleVC(vc: tabBarVC.selectedViewController)
            } else {
                if let presentedVC = vc?.presentedViewController {
                    return UIWindow.visibleVC(vc: presentedVC)
                } else {
                    return vc
                }
            }
        }
    }
    

    inside that file add function

    func visibleViewController() -> UIViewController? {
        let appDelegate = UIApplication.shared.delegate
        if let window = appDelegate!.window {
            return window?.visibleViewController
        }
        return nil
    }
    

    And if you want to use it, you can call it anywhere. Example:

      override func viewDidLoad() {
        super.viewDidLoad()
          if let topVC = visibleViewController() {
                 //show some label or text field 
        }
    }
    

    File code is like this:

    import UIKit
    
    public extension UIWindow {
        var visibleViewController: UIViewController? {
            return UIWindow.visibleVC(vc: self.rootViewController)
        }
    
        static func visibleVC(vc: UIViewController?) -> UIViewController? {
            if let navigationViewController = vc as? UINavigationController {
                return UIWindow.visibleVC(vc: navigationViewController.visibleViewController)
            } else if let tabBarVC = vc as? UITabBarController {
                return UIWindow.visibleVC(vc: tabBarVC.selectedViewController)
            } else {
                if let presentedVC = vc?.presentedViewController {
                    return UIWindow.visibleVC(vc: presentedVC)
                } else {
                    return vc
                }
            }
        }
    }
    
    func visibleViewController() -> UIViewController? {
        let appDelegate = UIApplication.shared.delegate
        if let window = appDelegate!.window {
            return window?.visibleViewController
        }
        return nil
    }
    
    0 讨论(0)
  • 2020-11-22 15:25

    in SWIFT 5.2

    you can use underneath code:

    import UIKit
    
    extension UIWindow {
        static func getTopViewController() -> UIViewController? {
            if #available(iOS 13, *){
                let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
                
                if var topController = keyWindow?.rootViewController {
                    while let presentedViewController = topController.presentedViewController {
                        topController = presentedViewController
                    }
                    return topController
                }
            } else {
                if var topController = UIApplication.shared.keyWindow?.rootViewController {
                    while let presentedViewController = topController.presentedViewController {
                        topController = presentedViewController
                    }
                    return topController
                }
            }
            return nil
        }
    }
    
    0 讨论(0)
  • 2020-11-22 15:26
    extension UIWindow {
    
        func visibleViewController() -> UIViewController? {
            if let rootViewController: UIViewController = self.rootViewController {
                return UIWindow.getVisibleViewControllerFrom(vc: rootViewController)
            }
            return nil
        }
    
        static func getVisibleViewControllerFrom(vc:UIViewController) -> UIViewController {
            if let navigationController = vc as? UINavigationController,
                let visibleController = navigationController.visibleViewController  {
                return UIWindow.getVisibleViewControllerFrom( vc: visibleController )
            } else if let tabBarController = vc as? UITabBarController,
                let selectedTabController = tabBarController.selectedViewController {
                return UIWindow.getVisibleViewControllerFrom(vc: selectedTabController )
            } else {
                if let presentedViewController = vc.presentedViewController {
                    return UIWindow.getVisibleViewControllerFrom(vc: presentedViewController)
                } else {
                    return vc
                }
            }
        }
    }
    

    Usage:

    if let topController = window.visibleViewController() {
        println(topController)
    }
    
    0 讨论(0)
提交回复
热议问题