I am trying to create a UIAlertController with two options 'Cancel' and 'Log out'. I want the 'Cancel' button to cancel the alert and the 'Log out' button to perform the segue associated with it, which i have set up in the storyboard.
My code is;
class HomeVC: UIViewController {
#IBAction func SignOutBtn(sender: UIButton) {
let alertController = UIAlertController(title: "Alert",
message: "Are you sure you want to log out?",
preferredStyle: .Alert)
let cancelAction = UIAlertAction(title:"Cancel",
style: .Cancel) { (action) -> Void in
print("You selected the Cancel action.")
}
let submitAction = UIAlertAction(title:"Log out",
style: .Default) { (action) -> Void in
print("You selected the submit action.")
self.presentedViewController
}
alertController.addAction(submitAction)
alertController.addAction(cancelAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
Well it seems your'e missing the actions you want to perform inside the blocks.
(also, you may want to dismiss the alert controller, inside the blocks as well.)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action) -> Void in
print("You selected the Cancel action.")
alertController.dismissViewControllerAnimated(true, completion: nil)
})
let submitAction = UIAlertAction(title: "Log out", style: .Default, handler: { (action) -> Void in
print("You selected the submit action.")
alertController.dismissViewControllerAnimated(true, completion: { () -> Void in
// Perform your custom segue action you need.
})
})
If you have set up a segue from one view to another, in your button handler for log out then you can call self.performSegueWithIdentifier("storyboadIdentifier") which will call the prepareForSeguemethod so you can modify or pass info along the segue if need be.
#pbush25
class HomeVC: UIViewController {
#IBAction func SignOutBtn(sender: UIButton) {
let alertController = UIAlertController(title: "Alert",
message: "Are you sure you want to log out?",
preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action) -> Void in
print("You selected the Cancel action.")
alertController.dismissViewControllerAnimated(true, completion: nil)
})
let submitAction = UIAlertAction(title: "Log out", style: .Default, handler: { (action) -> Void in
print("You selected the submit action.")
alertController.dismissViewControllerAnimated(true, completion: { () -> Void in
self.performSegueWithIdentifier("segue", sender: nil)
})
})
alertController.addAction(submitAction)
alertController.addAction(cancelAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
Related
I create an alert with UIAlertController and add some action in it. But when I touch button on it and, nothing changed. (Include cancel button) so I can only restart this application can solve this question.
let alert = UIAlertController(title: “my alert”, message: “some message...”, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: “button1”, style: .default, handler: { (_) in
print(“button 1 up inside”)
}))
alert.addAction(UIAlertAction(title: “button2”, style: .default, handler: { (_) in
print(“button 2 up inside”)
}))
alert.addAction(UIAlertAction(title: “cancel”, style: .cancel, handler: { (_) in
}))
self.present(alert, animated: true, completion: nil)
Xcode 10 built.
I had a similar problem in an app using the Sprite Kit. Here was the solution:
let connectActionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
connectActionSheet.addAction(UIAlertAction(title: "Button1", style: .default, handler: { (action:UIAlertAction) in
//Code if this button is pressed
}))
connectActionSheet.addAction(UIAlertAction(title: "Button2", style: .default, handler: { (action:UIAlertAction) in
//Code if button2 is pressed
}))
connectActionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
let vc = self.view?.window?.rootViewController
if vc?.presentedViewController == nil {
vc?.present(connectActionSheet, animated: true, completion: nil)
}
The last 4 lines were what made it worked. I hope this helps you.
Thanks a lot! My view controller can’t close this alert because these code
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
}
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
}
I'm trying to fire an alert that asks if you want to save or delete a draft after pressing cancel. I'm quite close, but I can't seem to get it right.
I'm unwinding from 'ReplyMailViewController'(ViewController A) to 'MailContentViewController'(ViewController B).
I added the following code in ViewController A to show the alert and 'hold' the segue perform:
override func shouldPerformSegue(withIdentifier identifier: String?, sender: Any?) -> Bool {
if let ident = identifier {
if ident == "cancelDraft" {
let saveDraftActionHandler = { (action:UIAlertAction!) -> Void in
NSLog("EXIT")
}
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let deleteDraftAction = UIAlertAction(title: "Delete Draft", style: .destructive, handler: nil)
alertController.addAction(deleteDraftAction)
let saveDraftAction = UIAlertAction(title: "Save Draft", style: .default, handler: saveDraftActionHandler)
alertController.addAction(saveDraftAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
return false
}
}
return true
}
The segue holds with this code, but the issue is that I can't figure out how to continue the unwind segue after pressing 'Save Draft' for example.
I also have an unwind function in View Controller B, but I can't seem to figure out how I can use this one for this task:
#IBAction func cancelToMailContentViewController(_ segue: UIStoryboardSegue) {
}
Instead of perform the segue directly you need to show your UIAlertViewController first and according to the user response execute your segue or not
#IBAction func showAlertViewController(){
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let replyAction = UIAlertAction(title: "Delete Draft", style: .destructive, handler: nil)
let replyAllAction = UIAlertAction(title: "Save Draft", style: .default) { (action) in
//Do whatever you need here
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
self.performSegue(withIdentifier: "cancelDraft", sender: action) //executing the segue on cancel
}
alertController.addAction(replyAllAction)
alertController.addAction(replyAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
After this you only need to change the unwind segue action to execute this method, and your segue will be executed if you press cancel in the UIAlertViewController via self.performSegue(withIdentifier: #<SegueIdentifier>, sender: #<sender>)
First, make the alert with two options:
class ViewController: UIViewController {
#IBAction func showAlertButtonTapped(_ sender: UIButton) {
// create the alert
let alert = UIAlertController(title: "UIAlertController", message: "Save this work?", preferredStyle: UIAlertControllerStyle.alert)
// add the actions (buttons)
alert.addAction(UIAlertAction(title: "Hell Yeah", style: UIAlertActionStyle.default, handler: nil))
alert.addAction(UIAlertAction(title: "Hell No", style: UIAlertActionStyle.cancel, handler: nil))
// show the alert
self.present(alert, animated: true, completion: nil)
}
After this, you have to make the segue and then name it (also connect it by control dragging from the view controller yellow icon to the other view controller):
After that put this your code to execute the segue:
self.performSegue(withIdentifier: ":)", sender: self)
After that you are going to execute the segue when the user responds to the alert:
if buttonTitle == "Hell Yeah" {
elf.performSegue(withIdentifier: ":)", sender: self)
}
so, in the end, your code should look like this:
class ViewController: UIViewController {
#IBAction func showAlertButtonTapped(_ sender: UIButton) {
// create the alert
let alert = UIAlertController(title: "UIAlertController", message: "Save this work?", preferredStyle: UIAlertControllerStyle.alert)
// add the actions (buttons)
alert.addAction(UIAlertAction(title: "Hell Yeah", style: UIAlertActionStyle.default, handler: nil))
alert.addAction(UIAlertAction(title: "Hell No", style: UIAlertActionStyle.cancel, handler: nil))
// show the alert
self.present(alert, animated: true, completion: nil)
if buttonTitle == "Hell Yeah" {
self.performSegue(withIdentifier: ":)", sender: self)
}
}
}
I am building a game.
This game has a UITableViewController which serves as a Settings & Options feature.
One of the options that you can select is to switch the opponent from pass and play to an AI (or the other way around).
What I'd like to do is use a UIAlertController to intercept the touch, check for a game in progress, and prompt the user to cancel the change or continue.
I have implemented the code to do this within the override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) function.
My code is as follows:
if indexPath.section == 1 {
// Here we need to detect a game in progress and ask for a confirmation before switching to another mode.
if getGameInProgress() == true {
// Display choice dialog
alert = UIAlertController (title: alertCaption, message: alertMessage, preferredStyle: .Alert)
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {(action: UIAlertAction) -> Void in
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
return
})
alert.addAction(cancelAction)
let ok: UIAlertAction = UIAlertAction(title: "Confirm", style: .Default, handler: {(action: UIAlertAction) -> Void in
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
// Do nothing, just let the touch method continue...
})
alert.addAction(ok)
self.presentViewController (alert, animated: true, completion: nil)
}
if indexPath.row == 0 {
// "Pass and Play"
setOpponentPreference("Pass and Play")
}
if indexPath.row == 1 {
// "Virtual Robert"
setOpponentPreference("Virtual Robert")
}
if indexPath.row == 2 {
// "Virtual Nathan"
setOpponentPreference("Virtual Nathan")
}
// No matter which difficulty selected:
gameboard.setDifficulty()
// Create a method to reset the game, but without fading out the menu screen (the current new game method takes you directly to the game. The player may not want that in this instance.)
}
The problem I am having is that the alert controller displays and waits for input, but it does not prevent the rest of the didSelectRowAtIndexPath function form continuing.
How do I receive the users input before handling the touch on the cell?
Hello All you need is put your code inside of your completion section for your "Confirm" option, your code will be execute only when user tap on "Confirm" button of your UIAlertViewController
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
// Do nothing, just let the touch method continue...
})
so your code must be
if indexPath.section == 1 {
// Here we need to detect a game in progress and ask for a confirmation before switching to another mode.
if getGameInProgress() == true {
// Display choice dialog
alert = UIAlertController (title: alertCaption, message: alertMessage, preferredStyle: .Alert)
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {(action: UIAlertAction) -> Void in
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
return
})
alert.addAction(cancelAction)
let ok: UIAlertAction = UIAlertAction(title: "Confirm", style: .Default, handler: {(action: UIAlertAction) -> Void in
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
if indexPath.row == 0 {
// "Pass and Play"
setOpponentPreference("Pass and Play")
}
if indexPath.row == 1 {
// "Virtual Robert"
setOpponentPreference("Virtual Robert")
}
if indexPath.row == 2 {
// "Virtual Nathan"
setOpponentPreference("Virtual Nathan")
}
// No matter which difficulty selected:
gameboard.setDifficulty()
// Create a method to reset the game, but without fading out the menu screen (the current new game method takes you directly to the game. The player may not want that in this instance.)
})
alert.addAction(ok)
self.presentViewController (alert, animated: true, completion: nil)
}
}
I hope this helps you, for me works great, regards
Sorry for the bad English. What I understand from you question is that you want to hold the program to continue execution till user select one of the button from UIAlertController.
for that you need to do is perform task inside the action of Ok button or Cancel button.
if getGameInProgress() == true {
// Display choice dialog
alert = UIAlertController (title: alertCaption, message: alertMessage, preferredStyle: .Alert)
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {(action: UIAlertAction) -> Void in
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
return
})
alert.addAction(cancelAction)
let ok: UIAlertAction = UIAlertAction(title: "Confirm", style: .Default, handler: {(action: UIAlertAction) -> Void in
//Do something in here like print
println("Confirm Button Pressed")
self.alert.dismissViewControllerAnimated(true, completion: { _ in })
// Do nothing, just let the touch method continue...
})
alert.addAction(ok)
self.presentViewController (alert, animated: true, completion: nil)
}
hope it help.
The issue at hand is the following: I show a UIAlertController. If the user presses delete, the view should go back to the first page, which is of the class class TableViewQuery: PFQueryTableViewController.
import UIKit
class DetailViewController: UIViewController {
var currentObject : PFObject?
#IBAction func pressDelete(sender: AnyObject) {
let deleteUser = UIAlertController(title: "Are you sure?", message: "Are you sure you want to delete the current user?", preferredStyle: UIAlertControllerStyle.Alert)
deleteUser.addAction(UIAlertAction(title: "Yes", style: .Default, handler: { (action: UIAlertAction) -> Void in
// Unwrap current object
if let object = self.currentObject {
object["firstName"] = self.firstName.text
object["lastName"] = self.lastName.text
object.deleteEventually()
}
}))
deleteUser.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction) -> Void in
//Do nothing
}))
presentViewController(deleteUser, animated: true, completion: nil)
}
I have tried self.dismissViewControllerAnimated(true, completion: nil), but that just closes the UIAlertController.
I also tried the unwind segue, but then it does that instantly when I press the button, instead of showing the UIAlertController.
I also tried the segueForUnwindingToViewController(<toViewController: UIViewController:UIViewController>, fromViewController: <#T##UIViewController#>, identifier: <#T##String?#>) BUT my toViewController isn't a UIViewController, but a PFQueryTableViewController.
Any ideas on what else I can try?
You should put code into handler of UIAlertAction to respond when user click YES. I guess your are using master detail view controllers. If so, you need to find the right navigation controller to pop. Else, If you are using navigation controller, just pop as the code I commented.
#IBAction func pressDelete(sender: AnyObject) {
let deleteUser = UIAlertController(title: "Are you sure?", message: "Are you sure you want to delete the current user?", preferredStyle: UIAlertControllerStyle.Alert)
deleteUser.addAction(UIAlertAction(title: "Yes", style: .Default, handler: { (action: UIAlertAction) -> Void in
// If you are using master detail view controllers
if let navController = self.splitViewController?.viewControllers[0] as? UINavigationController {
navController.popViewControllerAnimated(true)
}
// If you using navigation controller
// self.navigationController?.popViewControllerAnimated(true)
}))
deleteUser.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction) -> Void in
//Do nothing
}))
presentViewController(deleteUser, animated: true, completion: nil)
}
You should use the completion handler for presentViewController. You may need to keep track of any action the user took with the alert view controller. You will have to keep track of your user's choices with the alert view controller actions. Then in the completion handler check the user's choice and then make your navigation accordingly.
var didTapDeleteButton = false
#IBAction func pressDelete(sender: AnyObject) {
let deleteUser = UIAlertController(title: "Are you sure?", message: "Are you sure you want to delete the current user?", preferredStyle: UIAlertControllerStyle.Alert)
deleteUser.addAction(UIAlertAction(title: "Yes", style: .Default, handler: { (action: UIAlertAction) -> Void in
// Unwrap current object
if let object = self.currentObject {
object["firstName"] = self.firstName.text
object["lastName"] = self.lastName.text
object.deleteEventually()
didTapDeleteButton = true
}
}))
deleteUser.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction) -> Void in
didTapDeleteButton = false
}))
presentViewController(viewController, animated: true, completion: {
// Make navigation choice here
if didTapDeleteButton == true {
// Navigation option 1
} else {
// Navigation option 2
}
})
I'm quite new to Swift (and coding in general) and to this website.
I'm having a little bit of an issue now. In my app, I have an alert when a timer reaches 0. In that alert, there are 2 buttons. One says "Share" and the other says "Continue". I want to make it such that when a user taps "Continue", the next Storyboard will be shown to them. As of now, whatever button I press will dismiss the alert, but stay on the same Storyboard. (It also prints to the console which button I pressed, but of course that's just for me to see).
How do I go about doing this? Here is my code, in case anyone wants to know.
let alert = UIAlertController(title: "Time's Up!", message: "What would you like to do now?", preferredStyle: .Alert)
let firstAction = UIAlertAction(title: "Continue", style: .Default) { (alert: UIAlertAction!) -> Void in
NSLog("You pressed button one")
}
let secondAction = UIAlertAction(title: "Share", style: .Default) { (alert: UIAlertAction!) -> Void in
NSLog("You pressed button two")
}
alert.addAction(firstAction)
alert.addAction(secondAction)
presentViewController(alert, animated: true, completion:nil)
Try with this:
// Create the alert controller
var alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)
// Create the actions
var okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) {
UIAlertAction in
NSLog("OK Pressed")
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("someViewController") as UIViewController
self.presentViewController(vc, animated: true, completion: nil)
}
var cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) {
UIAlertAction in
NSLog("Cancel Pressed")
//do whatever you want here
}
// Add the actions
alertController.addAction(okAction)
alertController.addAction(cancelAction)
// Present the controller
self.presentViewController(alertController, animated: true, completion: nil)
If you haven't already set your ViewControllerIdentifier:
You need to set the Identifier value that you can find on the right column
Here is the code that might help you. When you create a AlertController with actions, you can provide the actions and style of the button when you define them. In code below action is in the closure (Block) and style is defined as .Default or .Cancel
let alert = UIAlertController(title: "Time's Up!", message: "What would you like to do now?", preferredStyle: .Alert)
let firstAction = UIAlertAction(title: "Continue", style: .Default) { (alert: UIAlertAction!) -> Void in
// Action when you press button goes here
print("Here you show next storyboard item.")
// Code to push new ViewController. For example :
self.navigationController?.pushViewController(newVCInstance, animated: true)
}
let secondAction = UIAlertAction(title: "Share", style: .Default) { (alert: UIAlertAction!) -> Void in
print("Here you share things.")
// Code to share things.
}
let thirdAction = UIAlertAction(title: "Cancel", style: . Cancel) { (alert: UIAlertAction!) -> Void in
print("Just dismissing the Alert Controller.")
}
alert.addAction(firstAction)
alert.addAction(secondAction)
alert.addAction(thirdAction)
presentViewController(alert, animated: true, completion:nil)