So, I have self
as UIWindow
, but how can I get visibleViewController at current moment?

- 2,132
- 17
- 34
-
have you use UINavigationController? – Hardik Shekhat Mar 01 '17 at 10:09
5 Answers
IN swift3:
func getVisibleViewController(_ rootViewController: UIViewController?) -> UIViewController? {
var rootVC = rootViewController
if rootVC == nil {
rootVC = UIApplication.shared.keyWindow?.rootViewController
}
if rootVC?.presentedViewController == nil {
return rootVC
}
if let presented = rootVC?.presentedViewController {
if presented.isKind(of: UINavigationController.self) {
let navigationController = presented as! UINavigationController
return navigationController.viewControllers.last!
}
if presented.isKind(of: UITabBarController.self) {
let tabBarController = presented as! UITabBarController
return tabBarController.selectedViewController!
}
return getVisibleViewController(presented)
}
return nil
}
If you add the child view controller:
let viewControllersVisible = self.rootViewController?.childViewControllers.filter({ $0.isVisible && $0.view.window })
This returns an array of UIViewControllers
added in your view hierarchy, it doesn't say if the user is actually able to see those view controllers, depends on your hierarchy.
if you present modally just a view controller:
let viewControllerVisible = self.rootViewController?.presentedViewController

- 4,058
- 1
- 29
- 49
You should check out this answer. The gist of it is that you start with the window's .rootViewController
. In my own code (using a UINavigationController
as the .rootViewController
, I use this (in AppDelegate
):
if let nvc = self.window?.rootViewController as? UINavigationController {
if let mvc = nvc.topViewController as? MasterViewController {
// ... do something
} else if let dvc = nvc.topViewController as? DetailViewController {
// ... do something
}
}
Note that if you are using the default template for a Master-Detail application, you will need to consider the SplitViewController
which interposes itself, but that should be reasonably obvious from the boilerplate code.
Inorder to get a reference to the top most view controller in the hierarchy try the following code
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController)
{
topController = topController.presentedViewController;
}
return topController;

- 1,818
- 4
- 25
- 47
If you want the topmost view on window try with this you will get the view.
[[[[UIApplication sharedApplication] keyWindow] subviews] lastObject];

- 5,055
- 2
- 22
- 42