How to get the current displaying UIViewController not in AppDelegate?
Solution 1
I do not like using 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 get top most view 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
}
}
Solution 2
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 Swift 4 project
Pangu
Updated on June 22, 2022Comments
-
Pangu almost 2 years
I'm trying to get the currently display
UIViewController
that is not in the AppDelegate, but it seems to always get the initial topUIViewController
, and not the present one.The following code in AppDelegate DOES get the current
UIViewController
present, but this same function does not work when I use it in any one 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 in a similar question: Get the current displaying UIViewController on the screen in AppDelegate.m
No matter how deep down I segue to, I can only retrieve the first-most View Controller.
How can I get the current presenting
UIViewController
?FYI: I'm NOT using a
UINavigationController
, just regularUIViewController
classes.-
Lefteris over 7 yearsAre you using a navigation controller ?
-
Pangu over 7 years@Lefteris: updated...thanks
-
-
Pangu over 7 yearsthis does not work, I put this in VC2 but it still grabs the top-most VC, i.e. VC1 even though I segued from VC1->VC2
-
Markicevic over 7 yearsDid you try using debug and "po" to see how you can get VC2?
-
Markicevic over 7 yearsEnter debug mode in xcode, and you have po ( print object) command in xcode terminal. You can print your current vc and found out how to get to top presented.
-
Markicevic over 7 yearsThis is example how to use po stackoverflow.com/a/11513877/5324438
-
KMC about 7 yearsI know it's been like 4 months but could you explain what your code does. It works perfect for me. But I just want to understand how it achieves.
-
Markicevic about 7 years@user30646 I added improved version of this, it just enumerates trough view controller until it finds last one.