Based on the following code, commands in closure in alert function are executed before User interface be executed. It causes, the variables in closure be empty?
func callAlert2() {
let alert = UIAlertController(title: "Add Contact", message: "Please fill the form", preferredStyle: .alert)
alert.addTextField { textField in
textField.placeholder = "Name"
self.contact.name = textField.text
}
alert.addTextField { (textField) in
textField.placeholder = "Surname"
self.contact.surname = textField.text
}
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Add", style: .default, handler: { (action) in
if let name = alert.textFields?.first?.text {
self.allContacts.append(self.contact)
}
}))
self.present(alert, animated: true, completion: nil)
}
Seems like you miss understood addTextField(configurationHandler:)
as per docs
A block for configuring the text field prior to displaying the alert. This block has no return value and takes a single parameter corresponding to the text field object. Use that parameter to change the text field properties.
Link: https://developer.apple.com/documentation/uikit/uialertcontroller/1620093-addtextfield
You are expecting your self.contact
object's name
and surname
to be updated inside configuration block but that will never happen. This closure/block is intended only for configuring the textfield and not to capture user input.
Inside this closure you can modify textFields property like placeholder, background color, border etc etc to configure it before being rendered. But if you want to capture the user input, use actions closure.
Rather
alert.addAction(UIAlertAction(title: "Add", style: .default, handler: { (action) in
if let name = alert.textFields?.first?.text,
(alert.textFields?.count ?? 0) >= 1,
let surname = alert.textFields?[1].text {
self.contact.name = name
self.contact.surname = surname
self.allContacts.append(self.contact)
}
}))
Hope this helps