I'm trying to figure out is how to create a pop up window that only appears once when you start the app and then won't appear again unless you close the app and reboot it. However, if you view the code below, you will realize that the alert will pop up every time the ViewController appears. For example, if you go to the settings tab and then return to the main ViewController, then the alert will pop up.
override func viewDidAppear(animated: Bool) {
let alertController = UIAlertController(title: "Disclaimer", message: "WARNING: Please ride carefully!", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Accept", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
Just create a global variable that is a Bool. If the app is opened it starts at false. Then once the disclaimer is seen it sets the variable to true. Then present the View Controller based on the value of the variable.
var disclaimerHasBeenDisplayed = false
class ViewController {
override func viewDidAppear(animated: Bool) {
if disclaimerHasBeenDisplayed == false {
disclaimerHasBeenDisplayed = true
let alertController = UIAlertController(title: "Disclaimer", message: "WARNING: Wakeboarding is fun, however it can be highly dangerous.
Wake Dice is not liable for any injuries obtained while wakeboarding. Please ride carefully!", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Accept", style: UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
}
}
Related
I want to have an alert action change the text of a UILabel in my View. Code below:
#IBAction func statusChange(_ sender: UIButton){
let playalert = UIAlertController(title: "OPERATION: \(sender.accessibilityIdentifier!) NOT POSSIBLE", message: "Convert op to PLAY mode to proceed", preferredStyle: .alert)
let recordalert = UIAlertController(title: "OPERATION: \(sender.accessibilityIdentifier!) NOT POSSIBLE", message: "Convert op to STOP mode to proceed", preferredStyle: .alert)
let statechangealert = UIAlertController(title: "OPERATION: \(sender.accessibilityIdentifier!) WILL NOW PROCEED", message: "", preferredStyle: .alert)
let stopAction = UIAlertAction(title: "Convert", style: .default, handler: { action in
self.statusDVR.text = "STOP"//"\(sender.accessibilityIdentifier!)"
})
let continueAction = UIAlertAction(title: "Continue", style: .default, handler: { action in
self.statusDVR.text = ""//"\(sender.accessibilityIdentifier!)"
})
let returnAction = UIAlertAction(title: "Return", style: .default, handler: { action -> Void in
})
playalert.addAction(stopAction)
playalert.addAction(returnAction)
recordalert.addAction(stopAction)
recordalert.addAction(returnAction)
statechangealert.addAction(continueAction)
//record was tapped, check if DVR stopped first
if (sender.tag == 5 && pwrStat == true ) {
//if not stopped send alert
if statusDVR.text != "STOP" {
self.present(recordalert, animated:true, completion: nil)
//if user tapped returned action
if statusDVR.text != "STOP" {
self.present(statechangealert, animated:true, completion: nil)
} else {
return
}
} else {
statusDVR.text = "RECORD"
}
The stopAction should convert a UILAbel called statusDVR in the view controller, but it doesn't do it.
I haven't tried implementing the other Actions yet, because I am stuck trying to figure out why my UILabel's text won't change. Thank you for any help :)
First of all, this code makes no sense:
if statusDVR.text != "STOP" {
self.present(recordalert, animated:true, completion: nil)
if statusDVR.text != "STOP" {
self.present(statechangealert, animated:true, completion: nil)
That code tries to present two alerts at the same time. That is illegal.
I think you think that when you say
self.present(recordalert, animated:true, completion: nil)
...your code magically comes to a stop while the user interacts with the alert and then proceeds after the user dismisses the alert. That’s not the case. Your code never magically stops; it just keeps right on going.
As for the actual question you asked about, the problem is simply that what you're doing is illegal:
playalert.addAction(stopAction)
playalert.addAction(returnAction)
recordalert.addAction(stopAction)
recordalert.addAction(returnAction)
No! You cannot take one UIAlertAction and somehow magically "share" it between two different UIAlertControllers. Every UIAlertController needs UIActions that belong to it alone. In other words, do not call addAction on the same UIAlertAction twice.
Just to demonstrate more simply, try running this code:
let action1 = UIAlertAction(title: "Test", style: .default) {
_ in print("test")
}
let alert1 = UIAlertController(title: "Hello", message: nil, preferredStyle: .alert)
let alert2 = UIAlertController(title: "Hello2", message: nil, preferredStyle: .alert)
alert1.addAction(action1)
alert2.addAction(action1)
self.present(alert1, animated: true, completion: nil)
The alert appears, you tap the Test button, the alert disappears — but nothing prints in the console. Now comment out the next to last line:
// alert2.addAction(action1)
... and run the code again. This time, when you tap Test, "test" appears in the console.
I am trying to implement the Action sheet in Swift. Below is the code to implement it. When i execute the code, Xcode does not show any errors and the action sheet does not appear in the simulator. Any help in resolving the issue is much appreciated.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
func showActionSheet(sender: AnyObject) {
let actionSheetController: UIAlertController = UIAlertController(title: "Action Sheet", message: "Choose an option!", preferredStyle: .actionSheet)
//Create and add the Cancel action
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in
//Just dismiss the action sheet
}
actionSheetController.addAction(cancelAction)
self.present(actionSheetController, animated: true, completion: nil)
The way your code is provided, it looks as if you added a method/function inside viewWillAppear. If that is not a typing mistake and you did indeed set your code up like that, modifying your code to look like this will get it to work:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let actionSheetController: UIAlertController = UIAlertController(title: "Action Sheet", message: "Choose an option!", preferredStyle: .actionSheet)
//Create and add the Cancel action
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in
//Just dismiss the action sheet
}
actionSheetController.addAction(cancelAction)
self.present(actionSheetController, animated: true, completion: nil)
}
Basically, do not have a method inside viewWillAppear but also move your action sheet display code to viewDidAppear instead of viewWillAppear
I want to show user a message once.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let defaultsDatafirstTrue = NSUserDefaults.standardUserDefaults()
if let _ = defaultsDatafirstTrue.stringForKey("firstTrue") {
} else {
let alertController = UIAlertController(title: "You can add road markers just do long press on the Map", message: "", preferredStyle: .Alert)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action:UIAlertAction) in
}
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true, completion:nil)
defaultsDatafirstTrue.setObject("true", forKey: "firstTrue")
}
}
But I have error Warning: Attempt to present <UIAlertController: 0x7c2a8000> on <****: 0x7d193800> whose view is not in the window hierarchy! Because at the first run the iOS app displays a warning to the user that will use the location determination.
How can I see my message after the system message?
Run the code from viewDidAppear: not from viewWillAppear:.
The problem with viewWillAppear: is that it is called before the view is actually visible, so you cannot present another view from it yet. Also, viewWillAppear: can be actually called multiple times and then cancelled (e.g. for interactive transitions).
I am trying to make an alert by pressing a button "delete data". My button is in a view which is inside a navigation controller. Here is my current code
class SomeViewController: UIViewController {
#IBAction func deleteData(sender: UIButton) {
let alert = UIAlertController(title: "delete Data", message: "Do you want to delete the data", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default, handler: nil))
alert.addAction(UIAlertAction(title: "No", style: UIAlertActionStyle.Default, handler: nil))
}
}
But is gives me the following error:
Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior
You've created your alert view controller but you still need to present it:
self.presentViewController(alert, animated: true, completion: nil)
You can read an article on the topic on appcoda.com
for showing alert use:
self.presentViewController(myAlert, animated: true, completion: nil)
and for dismiss use:
alert.dismissViewControllerAnimated(true, completion:nil)
I'm having a web view that displays a company's address and phone number and email. The current behavior is when the phone number is tapped it is then dialled immediately.
Is there a way for me to prompt an alert view to let user confirm the call? Instead of calling it immediately?
Here is the function I use to initialize an alert:
func displayAlert(title: String, message: String) {
var alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { (ACTION) -> Void in
// self.dismissViewControllerAnimated(true, completion: nil)
alert.hidesBottomBarWhenPushed = true
}))
print("running Activityindicator code")
self.presentViewController(alert, animated: true, completion: nil)
}
and I call it like so:
self.displayAlert("Alert title", message: "alert message")
hope this helps!