in my iOS actionsheet, I am showing Names from the JSON dictionary:
[
{ "Name": "Doctor for Disease AAA",
"Doctor_id": "21"
},
{ "Name": "Doctor for Disease BBB",
"Doctor_id": "22"
},
{ "Name": "Doctor for Disease AAA",
"Doctor_id": "25"
}
]
So, on button click delegate, I can get the button index and can fetch the corresponding 'Name' and 'Doctor_id'. This is working fine.
But now it seems like 'UIActionSheet' is deprecated, and I have to use 'UIAlertController'. As I have a large data, I am iterating through my array values and calling the alertcontroller handler (so a single function for all button click). But how can I get the button index from UIAlertController, so that I can fetch the 'Name' and 'Doctor_id' simultaneously.
Please help me.
You have multiple possibilities here.
find
to get the UIAlertAction
indexfind
let you find the index of an object in an array. You can use it to find
the index of the action
(that is passed as the parameter of the UIAlertAction
's handler, which is the UIAlertAction
itself) in the alert.actions
array of all actions.
let alert = UIAlertController(title: "Doctors", message: "Choose a doctor", preferredStyle: .ActionSheet)
let closure = { (action: UIAlertAction!) -> Void in
let index = find(alert.actions as! [UIAlertAction], action)
println("Index: \(index)")
}
alert.addAction(UIAlertAction(title: "Doc1", style: .Default, handler: closure))
alert.addAction(UIAlertAction(title: "Doc2", style: .Default, handler: closure))
alert.addAction(UIAlertAction(title: "Doc3", style: .Default, handler: closure))
alert.addAction(UIAlertAction(title: "Doc4", style: .Default, handler: closure))
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel) { _ in
println("User cancelled.")
})
self.presentViewController(alert, animated: true) {}
Create a closure that takes a parameter of your choice (here an Int
) and return a closure that captures that parameter so you can use it
let alert = UIAlertController(title: "Doctors", message: "Choose a doctor", preferredStyle: .ActionSheet)
let closure = { (index: Int) in
{ (action: UIAlertAction!) -> Void in
println("Index: \(index)")
}
}
alert.addAction(UIAlertAction(title: "Doc1", style: .Default, handler: closure(0)))
alert.addAction(UIAlertAction(title: "Doc2", style: .Default, handler: closure(1)))
alert.addAction(UIAlertAction(title: "Doc3", style: .Default, handler: closure(2)))
alert.addAction(UIAlertAction(title: "Doc4", style: .Default, handler: closure(3)))
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel) { _ in
println("User cancelled.")
})
self.presentViewController(alert, animated: true) {}
This way you have a function (closure) that generate closures for your UIAlertAction
handlers, all with the same body except that they capture a different object (a different Int
here).
What is really great with this solution is that you can capture anything. You can even capture an hypothetic Doctor
object that represent your doctor, or directly the doctor ID, etc.!
But generally you will add your actions using a for
loop, so why not take advantage of that, plus take advantage of closure and the fact that they capture variables, to make a nice function that will directly tell your the selected doctor's ID?
func testMyAlert() {
let doctors = [
["Name": "Doctor for Disease AAA", "Doctor_id": "21"],
["Name": "Doctor for Disease BBB", "Doctor_id": "22"],
["Name": "Doctor for Disease AAA", "Doctor_id": "25"]
]
chooseDoctor(doctors) { selectedDocID in
if let docID = selectedDocID {
println("User selected doctor with ID \(docID)")
} else {
println("User cancelled, no doctor selected")
}
}
}
func chooseDoctor(doctors: Array<[String:String]>, completion: Int?->Void) {
let alert = UIAlertController(title: "Doctors", message: "Choose a doctor", preferredStyle: .ActionSheet)
for doc in doctors {
let action = UIAlertAction(title: doc["Name"]!, style: UIAlertActionStyle.Default) { _ in
// On selecting this action, get the doctor's ID, convert it to an Int, and return that.
completion(doc["Doctor_id"]?.toInt())
}
alert.addAction(action)
}
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) { _ in completion(nil) } )
self.presentViewController(alert, animated: true) {}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With