UIAlertController - Waiting for user response - swift

code 3 will be executed despite no response. How to wait for an answer?
let alert = UIAlertController(title: "test", message: "Please answer: yes or not ?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (action) in alert.dismiss(animated: true, completion: nil)
// code 1...
}))
alert.addAction(UIAlertAction(title: "No", style: .default, handler: { (action) in alert.dismiss(animated: true, completion: nil)
// code 2...
}))
self.present(alert, animated: true, completion: nil)
// code 3...

Use closures for the handler parameter, and wait for the user's response:
func checkIfYesOrNo(handler: ((UIAlertAction) -> Void)? = nil) {
let alert = UIAlertController(title: "test", message: "Please answer: yes or not ?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: handler))
alert.addAction(UIAlertAction(title: "No", style: .default, handler: handler))
present(alert, animated: true, completion: nil)
}
Usage:
checkIfYesOrNo { action in
if action.title == "Yes" {
print("YES")
// code 3...
} else {
print("NO")
// code 3...
}
}

You can create a function to get output of your alert with completion handler like this.. Easy to use
func showAlert(completion: #escaping (Bool) -> Void) {
let alert = UIAlertController(title: "test", message: "Please answer: yes or not ?", preferredStyle: .alert)
// add the actions (buttons)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: {action in
// code 1...
completion(true)
}))
alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.cancel, handler: { action in
// code 2...
completion(false)
}))
present(alert, animated: true, completion: nil)
}
How to use
showAlert { isSuccess in
isSuccess ? print("true") : print("false")
// isSuccess is bool having true or false accordingly
// code 3... here
}

Related

How to enable a Uialertview specific button in iOS after it is clicked, using Swift?

on Button clear history I want to enable other 2 buttons. I am new in iOS.
let alert = UIAlertController(title: "Title", message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
let markAction = UIAlertAction(title: "Mark as Urgent", style: .default, handler: { (action) in
})
let resolveAction = UIAlertAction(title: "Resolvethe conversion", style: .default, handler: { (action) in
})
markAction.isEnabled = false
resolveAction.isEnabled = false
alert.addAction(markAction)
alert.addAction(UIAlertAction(title: "Clear history", style: .default, handler: { (action) in
alert.actions.map {$0.isEnabled = true}
}))
self.present(alert, animated: true, completion: nil)
}
You can enable your actions in the clear button completion handler and present again your alert because you cannot avoid the dismiss:
let alert = UIAlertController(title: "Title", message: nil, preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
let markAction = UIAlertAction(title: "Mark as Urgent", style: .default, handler: { (action) in
// TODO: Your action
})
markAction.isEnabled = false
alert.addAction(markAction)
alert.addAction(UIAlertAction(title: "Clear history", style: .default, handler: { (action) in
alert.actions.map {$0.isEnabled = true}
self.present(alert, animated: true, completion: nil)
}))
self.present(alert, animated: true, completion: nil)

How to segue with AlertView?

This is the code for the alert. The problem is that I want to segue to another VC when the user press the button "Ja" which means "Yes" In english.
#IBAction func TillbakaAction(_ sender: UIButton)
{
createAlert(title: "Är du säker på att du vill börja om?", message: "Ifyllda betyg nollställs")
}
func createAlert (title:String, message:String)
{
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
//CREATING ON BUTTON
alert.addAction(UIAlertAction(title: "Ja", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
print ("Jag vill gå tillbaka")
}))
alert.addAction(UIAlertAction(title: "Nej", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
print("Nej, jag vill inte gå tillbaka")
}))
self.present(alert, animated: true, completion: nil)
There is no need to call dismiss with alert it will automatically dismiss the alert when you press any action of AlertController.
So simply add performSegue(withIdentifier:sender:) with your action.
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ja", style: .default, handler: { (action) in
print ("Jag vill gå tillbaka")
// call the segue at hare
self.performSegue(withIdentifier:"SegueIdentifer", sender: nil)
}))
alert.addAction(UIAlertAction(title: "Nej", style: .default, handler: { (action) in
print("Nej, jag vill inte gå tillbaka")
}))
self.present(alert, animated: true)
#IBAction func TillbakaAction(_ sender: UIButton)
{
createAlert(title: "Är du säker på att du vill börja om?", message: "Ifyllda betyg nollställs")
}
func createAlert (title:String, message:String)
{
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
//CREATING ON BUTTON
alert.addAction(UIAlertAction(title: "Ja", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
print ("Jag vill gå tillbaka")
// call the segue at hare
}))
alert.addAction(UIAlertAction(title: "Nej", style: UIAlertActionStyle.default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
print("Nej, jag vill inte gå tillbaka")
}))
self.present(alert, animated: true, completion: nil)

Dismiss Alert Programmatically Swift

I need a little help with a UIAlert. I get an error "UIAlertController can only have one action with a style of UIAlertActionStyleCancel". I know it is because I am initiating this alert outside of the function, but unsure how to fix it. How can I get access to the alert within the if blah < 80 { conditional?
let alertView = UIAlertController(title: "Blah", message: "", preferredStyle: UIAlertControllerStyle.Alert)
#IBAction func blahButtonPressed(sender: AnyObject) {
alertView.addAction(UIAlertAction(title: "Do Something", style: .Default, handler: { (action: UIAlertAction!) in
// I have code here
}))
alertView.addAction(UIAlertAction(title: "Do Something 2", style: .Default, handler: { (action: UIAlertAction!) in
// I have code here
}))
alertView.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction!) in
// I have code here
}))
presentViewController(alertView, animated: true, completion: nil)
}
Later in the code I get values via Bluetooth and need to dismiss the Alert if a value is below 80.
if blah < 80 {
alertView.dismissViewControllerAnimated(true, completion: nil)
}
I'm not 100% but does it work when you only press the button once? If so, then it may be because you are adding the actions to your alertView inside the #IBAction. Instead, you may want to try moving the addition of the UIAlertAction's outside of the #IBAction and only presenting the alert view inside of it. Like so:
let alertView = UIAlertController(title: "Blah", message: "", preferredStyle: UIAlertControllerStyle.Alert)
alertView.addAction(UIAlertAction(title: "Do Something", style: .Default, handler: { (action: UIAlertAction!) in
// I have code here
}))
alertView.addAction(UIAlertAction(title: "Do Something 2", style: .Default, handler: { (action: UIAlertAction!) in
// I have code here
}))
alertView.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction!) in
// I have code here
}))
#IBAction func blahButtonPressed(sender: AnyObject) {
presentViewController(alertView, animated: true, completion: nil)
}
This way the UIAlertAction's don't get added every single time the "blahButton" is pressed (which would result in more than one UIAlertAction with style of "UIAlertActionStyleCancel")
Here is how I fixed it if anyone comes accross this.
var newAlert: AnyObject?
#IBAction func blahButtonPressed(sender: AnyObject) {
let alertView = UIAlertController(title: "Blah", message: "", preferredStyle: UIAlertControllerStyle.Alert)
alertView.addAction(UIAlertAction(title: "Do Something", style: .Default, handler: { (action: UIAlertAction!) in
// I have code here
}))
alertView.addAction(UIAlertAction(title: "Do Something 2", style: .Default, handler: { (action: UIAlertAction!) in
// I have code here
}))
alertView.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction!) in
// I have code here
}))
newAlert = alertView
presentViewController(alertView, animated: true, completion: nil)
}
// When I need to close. If blah is below 80
if blah < 80 {
if let newAlertView = newAlert as? UIAlertController {
newAlertView.dismissViewControllerAnimated(true, completion: nil)
}
}

Cannot call value of non-function type UIAlertAction

I'm not sure what's wrong with this function. I'm trying to present an alert asking if the user would like to delete the selected photo.
If the function that deletes the photo returns an error, I would like to show that error to the user.
Xcode is failing on the errorController.addAction line with the message that "cannot call value of non-function type UIAlertAction"
I'm using Swift 2
#IBAction func deletePhoto(sender: AnyObject) {
let alertController = UIAlertController(title: "Delete Photo", message: "Are you sure you want to delete this photo?", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style: .Default) { UIAlertAction in
self.photoGateway!.delete(self.photo!.id!, completion: { (withError: Bool) -> Void in
if (withError == true) {
let errorController = UIAlertController(title: "Delete Failed", message: "blah", preferredStyle: UIAlertControllerStyle.Alert)
// The next line is causing the error
errorController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(errorController, animated: true, completion: nil)
} else {
self.dismissViewControllerAnimated(true, completion: nil)
}
})
}
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { UIAlertAction in
print("Cancelled")
}
alertController.addAction(okAction)
alertController.addAction(cancelAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
If I take out the offending line then all works well, just the user has no way of dismissing the alert
Fixed it. Changed:
errorController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
to:
errorController.addAction(UIKit.UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil))
The reason this is happening is because the parameter for your callbacks is called UIAlertAction (lines 3 and 20 above) and this is overriding the declaration in UIKit. This is likely a mistake of code-completion. Just rename it to action or something like that or just _ as you don't reference it.

How to Call a Function when Ok is pressed in an UIAlert

Im try to simply call a function called "GoToNewShoot" When the user press the "ok" button when the Alert pops up Thanks!.
Code:
#IBAction func GobacktoCamera(sender: AnyObject) {
var alertController = UIAlertController(title: "Just Checking", message: "Are You Sure You Want to Start over ", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Cancel, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
You can do it by using handler from addAction this way:
#IBAction func GobacktoCamera(sender: AnyObject) {
var alertController = UIAlertController(title: "Just Checking", message: "Are You Sure You Want to Start over", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Yes", style: .Default, handler: { action in
//run your function here
self.GoToNewShoot()
}))
self.presentViewController(alertController, animated: true, completion: nil)
}
func GoToNewShoot(){
println("Method Called")
}
alerty.addAction(UIAlertAction(title: "Just Checking",
style: UIAlertActionStyle.Default,
handler: {(alert: UIAlertAction!) in print("Are You Sure You Want to Start over")}))