Search code examples
iosswiftxcodeuiviewcontrolleruialertcontroller

Present alert after dismissing View Controller


I'm using the newest Xcode and Swift version.

I'm presenting a specific View Controller like this:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let contactViewController = storyboard.instantiateViewController(identifier: "contactViewController")
show(contactViewController, sender: self)

I'm dismissing this View Controller like this:

self.presentingViewController?.dismiss(animated: true, completion: nil)

I want to present an UIAlertController right after dismissing the View Controller.

This:

self.presentingViewController?.dismiss(animated: true, completion: nil)

let alertMessage = UIAlertController(title: "Your message was sent", message: "", preferredStyle: .alert)
let alertButton = UIAlertAction(title: "Okay", style: UIAlertAction.Style.default)
alertMessage.addAction(alertButton)
self.present(alertMessage, animated: true, completion: nil)

… of course doesn't work because I cannot present an UIAlertController on a dismissed View Controller.

What's the best way to present this UIAlertController after the View Controller is dismissed?


Solution

  • You can do it in completion handler by getting top controller like this

    self.presentingViewController?.dismiss(animated: true, completion: {
                let alertMessage = UIAlertController(title: "Your message was sent", message: "", preferredStyle: .alert)
                   let alertButton = UIAlertAction(title: "Okay", style: UIAlertAction.Style.default)
                   alertMessage.addAction(alertButton)
                UIApplication.getTopMostViewController()?.present(alertMessage, animated: true, completion: nil)
            })
    

    Using this extension

    extension UIApplication {
    
        class func getTopMostViewController() -> UIViewController? {
            let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
            if var topController = keyWindow?.rootViewController {
                while let presentedViewController = topController.presentedViewController {
                    topController = presentedViewController
                }
                return topController
            } else {
                return nil
            }
        }
    }