How to get current UIViewController mapping not in AppDelegate?

I am trying to get the current UIViewController display, which is missing in AppDelegate, but it always gets the initial top UIViewController , not the current one.

The following code in AppDelegate MUST get the current UIViewController , but this same function does not work when I use it in any of my View controllers:

 func getTopViewController() -> UIViewController { var topViewController = UIApplication.sharedApplication().delegate!.window!!.rootViewController! while (topViewController.presentedViewController != nil) { topViewController = topViewController.presentedViewController! } return topViewController } 

The above code was provided as an answer on a similar question: Get the current display of the UIViewController on the screen in AppDelegate.m

No matter how deep I go, I can only get the first view of the View Controller.

How can I get the current presentation of the UIViewController ?

FYI: I am NOT using the UINavigationController , only the regular UIViewController classes.

+5
source share
2 answers

I do not like to use this, but sometimes it is necessary.

 static func getTopViewController() -> UIViewController { var viewController = UIViewController() if let vc = UIApplication.shared.delegate?.window??.rootViewController { viewController = vc var presented = vc while let top = presented.presentedViewController { presented = top viewController = top } } return viewController } 

** EDIT:

Here is an improved version, it will always have the top view of the controller.

 static var top: UIViewController? { get { return topViewController() } } static var root: UIViewController? { get { return UIApplication.shared.delegate?.window??.rootViewController } } static func topViewController(from viewController: UIViewController? = UIViewController.root) -> UIViewController? { if let tabBarViewController = viewController as? UITabBarController { return topViewController(from: tabBarViewController.selectedViewController) } else if let navigationController = viewController as? UINavigationController { return topViewController(from: navigationController.visibleViewController) } else if let presentedViewController = viewController?.presentedViewController { return topViewController(from: presentedViewController) } else { return viewController } } 
+18
source

Here is the same idea in one function:

 func topController(_ parent:UIViewController? = nil) -> UIViewController { if let vc = parent { if let tab = vc as? UITabBarController, let selected = tab.selectedViewController { return topController(selected) } else if let nav = vc as? UINavigationController, let top = nav.topViewController { return topController(top) } else if let presented = vc.presentedViewController { return topController(presented) } else { return vc } } else { return topController(UIApplication.shared.keyWindow!.rootViewController!) } } 

works for me in a Swift 4 project

+1
source

Source: https://habr.com/ru/post/1261079/


All Articles