In some cases my applications needs to display muliple Alert messages. Error messages are gathered on start and needs to be displayed to the user one at a time. When the first one is acknowledged, the next one should be presented. The problem is that they all try to execute at the same time, obviously. Is there a smart way to do this synchronously? Here is some code that simply describes what I want to do:
var errors : [NSError]!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let error1 = NSError(domain: "Test1", code: 1, userInfo: [NSLocalizedFailureReasonErrorKey : "Test1 reason."])
let error2 = NSError(domain: "Test2", code: 2, userInfo: [NSLocalizedFailureReasonErrorKey : "Test2 reason."])
let error3 = NSError(domain: "Test3", code: 2, userInfo: [NSLocalizedFailureReasonErrorKey : "Test3 reason."])
errors = [error1, error2, error3]
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
for error in errors {
self.showAlert(error)
}
}
func showAlert(error: NSError) {
var alert = UIAlertController(title: error.domain, message: error.localizedDescription, preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:nil))
self.presentViewController(alert, animated: true, completion: nil)
}
You are almost there. Having a buffer of alert messages is the correct idea. But instead of showing all the alerts immediately, you should move the showAlert()
call to the handler of the UIAlertAction
. So if one alert is dismissed, the next will be shown.
Something like this:
var errors : [NSError]!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let error1 = NSError(domain: "Test1", code: 1, userInfo: [NSLocalizedFailureReasonErrorKey : "Test1 reason."])
let error2 = NSError(domain: "Test2", code: 2, userInfo: [NSLocalizedFailureReasonErrorKey : "Test2 reason."])
let error3 = NSError(domain: "Test3", code: 2, userInfo: [NSLocalizedFailureReasonErrorKey : "Test3 reason."])
errors = [error1, error2, error3]
showError() // show an alert if errors are queued
}
func showError() {
if let error = errors.first {
let alert = UIAlertController(title: error.domain, message: error.localizedDescription, preferredStyle: .Alert)
let okayAction = UIAlertAction(title: "OK", style: .Default) { action in
self.errors.removeAtIndex(0) // remove the message of the alert we have just dismissed
self.showError() // show next alert if there are more errors queued
}
alert.addAction(okayAction)
presentViewController(alert, animated: true, completion: nil)
}
else {
println("All alerts shown")
}
}
Word of advice: Dismissing multiple alerts is very annoying. Maybe you could create a dedicated full screen viewController that shows all the error messages in a UITableView or something. This of course depends on the number of alert messages a typical user will see. If it's regularly more than three I would use a modal UIViewController which shows all messages at a glance.
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