swiftuiviewcontroller

Get top most UIViewController


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

UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(vc, animated: true, completion: nil)

However, it does not seem to do anything. The keyWindow and rootViewController seem to be non-nil values too, so the optional chaining shouldn't be an issue.

NOTE: It is a bad idea to do something like this. It breaks the MVC pattern.


Solution

  • 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
    }