Reputation: 2918
I have a simple use of UIAlertViewController in which I pass button labels and action functions as arguments to a function named showAlert() which sets up and invokes the alert. I have action function in UIAlertAction in the in
closure.
Unusual behavior: The action function gets executed as soon as the showAlert is executed instead of when the button is pressed.
The other issue is that the alert gets dismissed automatically when a button is pressed. I do not have dismiss statement.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
func test1() {
NSLog("test 1 executed")
}
@IBAction func show(_ sender: UIButton) {
self.showAlert(title: "Title", message: "Message",titleString: "A,B,C", function:test1())
}
func showAlert(title: String, message: String, titleString: String, function: ()) {
let cancelButtonTitle = NSLocalizedString("Cancel", comment: "")
let labels = titleString.components(separatedBy: ",")
var actions = [UIAlertAction()]
for label in labels {
let a = UIAlertAction(title: label, style: .default) { action in
function // executed as soon as showAlert is called!!
// Expecting to be called when button is pressed
NSLog("\(label) Pressed")
}
actions.append(a)
}
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
// Create the actions.
let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .cancel) { action in
NSLog("Cancel Button pressed.")
}
for action in actions {
alertController.addAction(action)
}
// Add the actions.
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
}
The response on the console is: 2017-05-11 11:55:15.593 AlertTest[5304:8818290] function executed 2017-05-11 11:55:25.287 AlertTest[5304:8818290] A Pressed
Upvotes: 0
Views: 32
Reputation: 271420
Remember this:
Adding ()s to the end of a method/function name will call the method. Remove the ()s to "refer" to that method/function.
When you are doing this:
// I mean this
// |
// v
self.showAlert(title: "Title", message: "Message",titleString: "A,B,C", function:test1())
You are calling test
and using its return value as the argument to showAlert
.
When that line is reached, test()
is called first to evaluate its return value, then showAlert
is called, hence the console output.
To refer to the method test
, remove the ()
s.
self.showAlert(title: "Title", message: "Message",titleString: "A,B,C", function:test1)
You also wrote the parameter type wrong. The type of function that takes no parameters and returns nothing should be () -> Void
:
func showAlert(title: String, message: String,
titleString: String, function: () -> Void) {
Also, in the alert closure, add the ()s to the function because you are now trying to call it:
let a = UIAlertAction(title: label, style: .default) { action in
function() // Note the ()s
NSLog("\(label) Pressed")
}
P.S. I don't think having all the buttons do the same thing is what you really want. I might be wrong though.
Upvotes: 1