How to use alert to confirm or cancel view transition?

590 Views Asked by At

On certain conditions, if users intent to leave the current view (e.g. pop the current view, push other view, or select other tab items etc.), a UIAlertController should be presented to confirm users' real intention.

Users can press OK to proceed the view transitioning, or Cancel to stay on the current view.

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if someConditions {
        promptUIAlert()
    }
}

Any solutions that can achieve that requirements?

2

There are 2 best solutions below

2
On BEST ANSWER

First of all, you cannot handle this is viewWillDisappear because at this point it has already been decided that the view will disappear. You need to handle this wherever you have view transitions (push, pop, present, dismiss).

You have to handle the transitions in the confirmation alert action. You alert would look something like this.

let alert = UIAlertController(title: "Wait!", message: "Are you sure you want to leave this view?", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default) { (alertAction) in
    //Handle view transitioning here
}
let cancel = UIAlertAction(title: "Cancel", style: .destructive) { (alertAction) in
    //Do nothing?
}
alert.addAction(ok)
alert.addAction(cancel)
present(alert, animated: true, completion: nil)
0
On

You can't intercept and retain the user in the same ViewController once the viewWillDissaper is fired. You should do it in advance. My suggestion is to add a UIBarButton with a label Back to the navigationItem.leftBarButtonItem and manually check whether the user wants to navigate or not. This is the closest you can get.

also, you can use the UIAlertViewController to confirm whether the user wants to navigate or not.

    //inside viewDidLoad
    navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(handleBack))

    //define another function to handle the selctor
    @objc func handleCancel(){
       if someConditions {
                promptUIAlert()
        }
    }

    //you function should be like this with UIAlertController
    func promptUIAlert(){
        let alertController = UIAlertController(title: "Error", message: "Some message", preferredStyle: .alert)
        let CancelAction = UIAlertAction(title: "Cancel", style: .default) { (action) in
         //type your custom code here for cancel action
        }
let OkAction = UIAlertAction(title: "OK", style: .default) { (action) in
         //type your custom code here for OK action
        }
        alertController.addAction(OKAction)
        alertController.addAction(CancelAction)

        self.present(alertController, animated: true)
    }

Doing something inside viewWillDissaper would be handy to save some unsaved data behind the screen. But not to prompt and ask the user whether they want to remain in the same ViewController.