Dismissal of UIAlertController (best practice)

14,651

Solution 1

The dismissal is "included" in the presentViewController call. You do not need a delegate because you have the completion block. In this block you put what you would normally put into the delegate callback, except the call to dismiss the alert.

As far as "best practice" is concerned, I noted that in many APIs, Apple replaced delegate callbacks with completion blocks. Apple typically recommends using the block syntax. I surmise this could be partly because it helps keeping the related code sections together.

Solution 2

There is an elegant way! Just write the action or function inside the alert controller's cancel action. (here the action style should be .cancel)

Code for Swift 3:

let Alert: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)

    let OkAction: UIAlertAction = UIAlertAction(title: “Ok”, style: .default) { ACTION in

       //Will be called when tapping Ok

    }

    let CancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) {ACTION in

      // Will be called when cancel tapped or when alert dismissed.
      // Write your action/function here if you want to do something after alert got dismissed”

    }

    Alert.addAction(OkAction)
    Alert.addAction(CancelAction)

present(Alert, animated: true, completion: nil)

Solution 3

Is some Cases you may like to use this:

  class MyAlertController : UIAlertController {
    var dismissHandler : (()->())?
    override func viewDidDisappear(_ animated: Bool) {
      dismissHandler?()
      super.viewDidDisappear(animated)
    }
  }

Usage:

  let alert = MyAlertController(title: ...
  let cancelButton = UIAlertAction(titl
  alert.dismissHandler = { /*...do something */ }
  alert.addAction(cancelButton)
  ...
Share:
14,651
Woodstock
Author by

Woodstock

From Ireland, interested in iOS, macOS & Linux development, cryptography, math, music, technology, running, lifting and good food... Currently working in Architecture and Applied Cryptography.

Updated on June 05, 2022

Comments

  • Woodstock
    Woodstock about 2 years

    When using UIAlertController like this:

    var alert = UIAlertController(title: "Core Location", 
         message: "Location Services Disabled!", 
         preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, 
         handler: nil))
    self.navigationController.presentViewController(alert, animated: true, 
         completion: nil)
    

    I noticed that the dismissal of the alert view is seemingly done automatically. Shouldn't the dismissal of a presented ViewController be done by the presenting ViewController via a delegate call?

  • Woodstock
    Woodstock almost 10 years
    Thanks - so we no longer need delegates for dismissing modal ViewControllers? - where is the dismissal call included?
  • Mundi
    Mundi almost 10 years
    It does not have to be done explicitly. When you press a button on the alert, it is dismissed automatically.
  • Jaysen Marais
    Jaysen Marais over 9 years
    This answer can be read to imply that the completion closure of the presentViewController:animated:completion method is invoked when the alert is dismissed. If you read it that way, be warned that this is not the case. As the docs say: "The completion handler is called after the viewDidAppear: method is called on the presented view controller". i.e. it has nothing to do with dismissal
  • Mundi
    Mundi over 9 years
    No, the completion argument of this method is for a "callback" after the animation presenting the view controller has finished. This makes sense - a non-modal view controller could stay up indefinitely. I agree that this could be confusing, but note that the parameter is not called "completion" but "handler", indicating that there is this important difference.
  • Thiha Aung
    Thiha Aung about 9 years
    stackoverflow.com/questions/30840235/…. Any Help with that please?
  • erikprice
    erikprice about 8 years
    In iOS 9 (and probably iOS 8 too), the completion block to -presentViewController:animated:completion: is executed just after the UIAlertController first appears. If you need a callback for when the user dismisses the alert controller, then provide a UIAlertAction whose type is UIAlertActionStyleCancel, and put your code in that object's handler. It will execute when the alert controller is dismissed by tapping outside of the popover or tapping the cancel button.
  • MatthewLuiHK
    MatthewLuiHK over 6 years
    First, the answer itself is not related to the topic. I think that guy is asking, why the design UIAlertController is so special that it aim to dismiss by itself. I think he definitely know, the normal way of UIViewController life cycle and management. I think you can talk more about how UIAlertController differentiate from the other and why it is. BTW the completion block of presentViewController(_:UIViewController, _:Bool, _:Void->()) is not designed to be call when a vc is "dismissed"(I guess you might mix up the usage of "the presenting vc is going to be dismiss" something )
  • Max
    Max almost 6 years
    If you want to do something on dismissal, you have to add it to every action because, for example, tapping OK also dismisses the alert.