Get top most UIViewController

后端 未结 24 1877
别那么骄傲
别那么骄傲 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:38

    In a very rare case, with custom segue, the top most view controller is not in a navigation stack or tab bar controller or presented, but its view is inserted to the top of key windown's subviews.

    In such situation, it's necessary to check if UIApplication.shared.keyWindow.subviews.last == self.view to determine if the current view controller is the top most.

    0 讨论(0)
  • 2020-11-22 15:40

    iOS13+ //top Most view Controller

    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 UIWindow.key!.rootViewController?.topMostViewController()
        }
    }
    
    extension UIWindow {
        static var key: UIWindow? {
            if #available(iOS 13, *) {
                return UIApplication.shared.windows.first { $0.isKeyWindow }
            } else {
                return UIApplication.shared.keyWindow
            }
        }
    }
    
    //use let vc = UIApplication.shared.topMostViewController()
    
    // End top Most view Controller
    
    0 讨论(0)
  • 2020-11-22 15:40
    class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
            if let navigationController = controller as? UINavigationController {
                return topViewController(controller: navigationController.visibleViewController)
            }
            if let tabController = controller as? UITabBarController {
                if let selected = tabController.selectedViewController {
                    return topViewController(controller: selected)
                }
            }
            if let presented = controller?.presentedViewController {
                return topViewController(controller: presented)
            }
            return controller
        }
    
    0 讨论(0)
  • 2020-11-22 15:41

    I loved @dianz's answer, and so here is the swift 3's version of it. It's basically the same thing but his was missing a curly brace and some of the syntax/variable/method names have changed. So here it is!

    extension UIApplication {
        class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
            if let nav = base as? UINavigationController {
                return topViewController(base: nav.visibleViewController)
            }
            if let tab = base as? UITabBarController {
                if let selected = tab.selectedViewController {
                    return topViewController(base: selected)
                }
            }
            if let presented = base?.presentedViewController {
                return topViewController(base: presented)
            }
            return base
        }
    }
    

    Usage is still the exact same though:

    if let topController = UIApplication.topViewController() {
        print("The view controller you're looking at is: \(topController)")
    }
    
    0 讨论(0)
  • 2020-11-22 15:43

    To find the visible viewController in Swift 3

    if let viewControllers = window?.rootViewController?.childViewControllers {
    
         let prefs = UserDefaults.standard
    
         if viewControllers[viewControllers.count - 1] is ABCController{
            print("[ABCController] is visible")
    
         }
    }
    

    This code find the last added or the last active controller visible.

    This I have used in AppDelegate to find active view Controller

    0 讨论(0)
  • 2020-11-22 15:45

    presentViewController shows a view controller. It doesn't return a view controller. If you're not using a UINavigationController, you're probably looking for presentedViewController and you'll need to start at the root and iterate down through the presented views.

    if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
        while let presentedViewController = topController.presentedViewController {
            topController = presentedViewController
        }
    
        // topController should now be your topmost view controller
    }
    

    For Swift 3+:

    if var topController = UIApplication.shared.keyWindow?.rootViewController {
        while let presentedViewController = topController.presentedViewController {
            topController = presentedViewController
        }
    
        // topController should now be your topmost view controller
    }
    

    For 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
    }
    
    0 讨论(0)
提交回复
热议问题