I'm working with a simple button that, when pressed, runs a function I created.
Originally, I wrote the code like this:
func askQuestion() {
// runs code to ask a question
}
@IBAction func buttonTapped(_ sender: UIButton) {
let ac = UIAlertController(title: title, message: "You tapped the button.", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Continue", style: .default, handler: askQuestion))
present(ac, animated: true)
But that returns an error:
Cannot convert value of type '() -> ()' to expected argument type '((UIAlertAction) -> Void)?'
Which is fixed when you add the following parameter to askQuestion():
askQuestion(action: UIAlertAction! = nil)
Why does a handler method passed into the UIAlertAction require that it accept a UIAlertAction parameter? It seems like an unnecessary step, but I was thinking it might be a way to scan your code for hints that this function is triggered by a button.
You could have a single handler responsible for handling multiple actions
var continueAction: UIAlertAction!
var cancelAction: UIAlertAction!
override func viewDidLoad() {
super.viewDidLoad()
continueAction = UIAlertAction(title: "Continue", style: .default, handler: masterHandler)
cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: masterHandler)
}
//...
let ac = UIAlertController(title: title, message: "You tapped the button.", preferredStyle: .alert)
ac.addAction(continueAction)
ac.addAction(cancelAction)
Personally, I don't know why you might do this, but the API designers felt it was a good idea to provide you with the flexibility to design your solution which best meet your needs.
So, in most cases, while I appreciate it seems weird (especially when you can use closures), I do appreciate having the information available to make my own choices