Dismissing a View Controller, then presenting an Alert Controller

4.7k Views Asked by At

In my project, I am using rootViewController?.dismiss to dismiss some View Controllers back to the main VC.

In the completion handler, I would like to present a UIAlertController on the main View Controller once it becomes visible again.

My problem is the UIAlertController never appears. My hunch is because I'm using self in the launchFrom parameter. Do I need to get a reference back to the main VC, and present it there?

Dismiss VC and try presenting Alert:

self.view.window!.rootViewController?.dismiss(animated: false, completion: {
    Constants.presentThankYou(launchFrom: self)
})

presentThankYou method

static func presentThankYou(launchFrom: UIViewController) {
    let alertController = UIAlertController(title: "Thank You!", message: "You did it!", preferredStyle: UIAlertControllerStyle.alert)
    let okAction = UIAlertAction(title: "Close", style: UIAlertActionStyle.default) { (result : UIAlertAction) -> Void in
        print("Done")
    }
    alertController.addAction(okAction)
    launchFrom.present(alertController, animated: true, completion: nil)
}

How do I present the Alert Controller after all of my VC's have been dismissed?

4

There are 4 best solutions below

0
On BEST ANSWER

Out of my head, Try doing it in viewDidAppear. To prevent the alert from showing up all the time, use a bool shouldShowThankYouAlert and set this value to true in the dismiss completion handler

0
On

You can also refer to this if required , Just call the alert to show in viewWillDisappear of Controller that is being dismissed

override func viewWillDisappear(_ animated: Bool) {
        if self.isMovingFromParentViewController {
            DispatchQueue.main.async {
                wrapperClass.BasicAlert("View is Dismissed", message: "", view: self)
            }
        }
    }

This will show Alert when view is dismissed Fully

0
On

I did not check that but how about using window instead of UIViewController.

self.view.window!.rootViewController?.dismiss(animated: false, completion: {
   Constants.presentThankYou()
})

static func presentThankYou() {
   let alertController = UIAlertController(title: "Thank You!", message: "You did it!", preferredStyle: UIAlertControllerStyle.alert)
   let okAction = UIAlertAction(title: "Close", style: UIAlertActionStyle.default) { (result : UIAlertAction) -> Void in
       print("Done")
    }
   alertController.addAction(okAction)
   appDelegate.window.present(alertController, animated: true, completion: nil)
}
7
On

So one problem, a completion block doesn't require the main-thread. I suggest forcing the completion to execute some code.

var topController: UIViewController? {
  if var temp = UIApplication.shared.keyWindow?.rootViewController {
    while let presentedViewController = temp.presentedViewController {
      temp = presentedViewController
    }
    return temp
  }
  return nil
}

self.view.window!.rootViewController?.dismiss(animated: false, completion: {
  DispatchQueue.main.async {
    guard let top = topController else { return }
    Constants.presentThankYou(launchFrom: top)
  }
})