How Should You Handle Closure Arguments for Uialertaction

How should you handle closure arguments for UIAlertAction


  1. Yes, you must always handle the argument. It's part of the signature and can't be ignored. It's also special Swift syntax being able to drop the handler parameter since it is the last parameter and it is a closure parameter.

  2. Change anything(action) to anything just like in the example you link to.

  3. You misunderstand. They are not saying you can drop the style parameter. They are saying you can drop the UIAlertActionStyle from UIAlertActionStyle.Default meaning you only need to pass .Default as the argument to the style parameter.

  4. You want an example of where the action parameter to the handler is useful. There aren't too many uses really. The only properties are the title, style, and whether it's enabled or not. The latter is pointless because if the handler was called you know it was enabled. The only possible use is if the title or style need to be used in the handler and they weren't hard coded into the alert action when it was created. By accessing the title or style properties in the handler, you have easy access to the actual values used when the action was created.

Is there a way to pass a closure to UIAlertAction that will return a String in Swift?

If I understood you correctly you could change your method signature to

showSerialNumberAlertController(completion: @escaping (String) -> Void)

and within this function change the continue action to:

let continueAction = UIAlertAction(title: "Continue", style: .default) { (_) in
let serialNumberField = alertController.textFields![0] as UITextField
let text = serialNumberField.text
completion(text ?? "")
}

Finally you call the method like this:

UIAlertController.showSerialNumberAlertController { serial in
print("Serial number entered: \(serial)")
}

UIAlertAction handler is non escaping?

UIAlertAction handler is escaping

because Optional closures are all implicitly escaping (thanks to @sweeper)

UIAlertAction - Handling Actions

You can add two handlers parameters to your showAlert method, one for the ok action and another for the cancel action. So your code might look something like this:

class AlertDialog {
class func showAlert(_ title: String, message: String, viewController: UIViewController,
okHandler: (() -> Swift.Void),
cancelHandler: (() -> Swift.Void)) {

let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default, handler: okHandler)
alertController.addAction(OKAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: cancelHandler)
alertController.addAction(cancelAction)
viewController.present(alertController, animated: true, completion: nil)
}
}

From your viewController you will call:

AlertDialog.showAlert("Ok", message: "Some Message", viewController: self, okHandler: {
//OK Action
},cancelAction: {
//Cancel Action
})

Writing handler for UIAlertAction

Instead of self in your handler, put (alert: UIAlertAction!). This should make your code look like this

    alert.addAction(UIAlertAction(title: "Okay",
style: UIAlertActionStyle.Default,
handler: {(alert: UIAlertAction!) in println("Foo")}))

this is the proper way to define handlers in Swift.

As Brian pointed out below, there are also easier ways to define these handlers. Using his methods is discussed in the book, look at the section titled Closures

Right way to make a UIAlertAction's handler

They are all the same, it's mostly a matter of syntactic style you prefer. Option 3 uses type inference and the trailing closure syntax, which is generally preferred as it's concise and gets rid of the extra set of parentheses as it moves the last argument closure outside of the function call. You could one-up option 3 by removing the parentheses around action, those aren't needed either.

More on this is explained in the Swift Programming Language book, see the section on Closures.

How to pass multiple handlers in UIAlertAction

It's not totally clear what you're asking, but if you are trying to figure out which button was pressed so that you can execute different methods for each one you can do something like this:

@IBAction func buttonClicked(_ sender: UIButton) {
let alert = UIAlertController(title: "Select Value", message: nil, preferredStyle: .actionSheet)
for list in self.listValue {
alert.addAction(UIAlertAction(title: list.value, style: .default, handler: { (action) in
// How do I call different handlers here?
// I'll need to retrieve alert.title in these handlers
switch action.title {
case "Value A":
print("It's Value A")
case "Value B":
print("It's Value B")
default:
print("We didn't implement anything for this value")
}
}))
}
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil))
self.present(alert, animated: false, completion: nil)
}

Passing Multiple Parameters to an UIAlertAction in Swift

Replace this line:

let joinAction = UIAlertAction(title: "Join", style: UIAlertActionStyle.default, handler: joinSelected(alert: <#UIAlertAction#>, source: source))

with:

let joinAction = UIAlertAction(title: "Join", style: UIAlertActionStyle.default, handler: { [weak self] _ in
joinSelected(source: source)
})

And update joinSelected to:

fileprivate func joinSelected(source: String) {


Related Topics



Leave a reply



Submit