Swift alert action handler not working specific case - ios

I'm creating an app that displays users comments. User enters a comment and then clicks submit button and then an alert action view should occur. I'm trying to direct a user to my fourthviewcontroller when the ok button in the alert view is clicked. Here is my code, it should work fine.
let alert = UIAlertController(title: "Succesful", message: "Successfully added!", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
let uivc = self.storyboard!.instantiateViewController(withIdentifier: "ViewController")
self.navigationController!.pushViewController(uivc, animated: true)
}))
self.present(alert, animated: true)
However, I get this error when I click on the OK button.
'InvalidPathValidation', reason: '(child:) Must be a non-empty string and not contain '.' '#' '$' '[' or ']''
FourthViewController is created based on the user's selections on the past three viewcontrollers. There is a unique fourthviewcontroller based on the combination of the tableview cells clicked in the previous view controllers. I believe the problem arises because when I direct the user to FourthViewController, the app does not know what the FourthViewController contains as there were no tableview cells clicked before. When I change the direction of the VC from FourthViewController to FirstViewController everything works amazingly.
Is it possible to fix this issue? I'd appreciate any help! Thank you very much and have a good day!

If I understood correctly, the FourthViewController has some variables which depend on the previous ViewControllers. In that case just initialise these variables setting their value: uivc.varName = value
You may also perform a segue instead of instantiating the view controller and you can set the values of the nextViewController in the prepare function.

Remove following line form action completion
let uivc = self.storyboard!.instantiateViewController(withIdentifier:"ViewController")
self.navigationController!.pushViewController(uivc, animated: true)
and make a function as below
func navigate(){
let uivc = self.storyboard!.instantiateViewController(withIdentifier:"ViewController")
self.navigationController!.pushViewController(uivc, animated: true)
}
now add following in action completion
self.navigate()
like below
let alert = UIAlertController(title: "Succesful", message: "Successfully added!", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
self.navigate()
}))
self.present(alert, animated: true)

Related

Alert Blocking Segue-iOS

I want to ask the user for permission (for which I am using UIAlert) before performing the segue. Once they have answered the question in the alert, I want to segue to the next View Controller, irrespective of their answer.
The code looks something like this:
showAlert() //Method showing the alert
performSegue(withIdentifier : "secondVC", sender : self)
The problem I am facing here is that the app is showing me the alert but not performing the segue.
Add a completion handler to your alert's dismiss button like this
let alert = UIAlertController(title: "Alert", message: "Content Here", preferredStyle: .alert)
// add textfield or whatever you need
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in
self.performSegue(withIdentifier: "secondVC", sender: self)
}))
present(alert, animated: true)
The completion handler will be called when the user presses the "OK" button on the alert.

Adding a segue to another view controller when specific action is picked from a popup

I'm trying to link a specific View Controller that will run when the user picks 'yes' off of a different pop up automatically generated after a random number is chosen.
How would I add the second view controller only when the user picks yes (and discards the pop up when the user picks no)?
I researched it on Stack already and someone suggested using Storyboard and Segues, so I have connected the first and second view controllers using "Show Segue to Weapon Pop Up View Controller", and the second VC has the storyboard ID of "PopUp".
Thanks for any help!
Here's my code:
#IBAction func rolld20(_ sender: Any) {
let randomnumber20 = Int.random(in: 1...20)
d20label.text = String(randomnumber20)
//create the alert
let d20alert = UIAlertController(title: "You rolled a D20!",
message: "You rolled a \(String(randomnumber20))! Is this enough?", preferredStyle: UIAlertController.Style.alert)
// add the actions (yes/no buttons)
d20alert.addAction(UIAlertAction(title: "Yes", style: UIAlertAction.Style.default, handler: nil)) {
//code to open up second view controller with the storyboard ID "PopUp" goes here I believe?
}
d20alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.cancel, handler: nil))
// show the alert when the user clicks to roll d20
self.present(d20alert, animated: true, completion: nil)
}
You need to implement performSegueWithIdentifier.
In your case, the code would be something like:
#IBAction func rolld20(_ sender: Any) {
let randomnumber20 = Int.random(in: 1...20)
let d20alert = UIAlertController(title: "You rolled a D20!",
message: "You rolled a \(String(randomnumber20))! Is this enough?", preferredStyle: UIAlertController.Style.alert)
d20alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (action) -> Void in
self.performSegue(withIdentifier: "PopUp", sender: nil)
}))
d20alert.addAction(UIAlertAction(title: "No", style: UIAlertAction.Style.cancel, handler: nil))
self.present(d20alert, animated: true, completion: nil)
}
I removed the comments for readability. Have in mind that the string identifier in the method is relative to the SEGUE identifier, not the destination view controller identifier. To set your segue identifier, simply click on the segue:
And edit the identifier on "Show the Attributes inspector" item:

How to show alert after unwind transition in iOS?

I'm implementing Login in iOS. I want to unwind to the previous VC(IntroVC) first, and to show completed sign up alert about completed in IntroVC.
(completingSignUp is Unwind function.)
#IBAction func completingSignUp(_ segue: UIStoryboardSegue) {
let completedAlert = UIAlertController(title: "Completing", message: "Congratulations.", preferredStyle: .alert)
let ok = UIAlertAction(title: "OK", style: .default, handler: nil)
completedAlert.addAction(ok)
self.present(completedAlert, animated: true)
}
It shows only the alert without unwind to IntroVC.
I think the location of the alert code seems to be incorrect.
Where should I write alert code?
Put the code into IntroVC‘s viewDidAppear. You will need to introduce a condition so that the alert is presented only when you are coming back via the unwind segue.

How to prevent viewing a view when clicking on a button (Swift)

I'm having a button on view that contains this condition:
FIRAuth.auth()?.addStateDidChangeListener { auth, user in
if let user = user {
self.performSegue(withIdentifier: "AddDevice", sender: nil)
}
else {
let alert = UIAlertController(title: "Sorry", message:"You Have to register", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default) { _ in })
self.present(alert, animated: true){}
}
}
To check whether the user is logged in or not!
If logged in the segue should run and open the next view
If not an alert should appear to the user.
But the next view contains a function that retrieved the current user data! (Logged in user) in viewDidLoad function!
So when the user not logged in and I click to this button I keep getting crash instead of the alert!
How can I prevent viewing the next view and just present the alert!
So I can avoid the crash?
From your description is sounds like the segue is always executing, but it's not what you want.
Connect the segue from the view controller itself, name it and put the whole method inside IBAction connected to the button.
Something like this:
#IBAction func loginDidTouch(sender: AnyObject) {
FIRAuth.auth()?.addStateDidChangeListener { auth, user in
if let user = user {
self.performSegue(withIdentifier: "AddDevice", sender: nil)
}
else {
let alert = UIAlertController(title: "Sorry", message:"You Have to register", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default) { _ in })
self.present(alert, animated: true){}
}
}
For illustration:
In the first image the segue is connected to the button. Therefore, every time the button is pressed it will execute the segue.
In the second image the segue is connected to the view controller and the button is only connected to the via the IBAction. Therefore, the button only triggers the action and the action triggers the segue.
This could easily checked by selecting the segue in storyboard

swift - UIAlertController takes the user back to the first ViewController

I use UIAlertController in my app and whenever the user clicks OK, it takes the user back to the first viewcontroller.
var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
func displayAlert(title:String, error: String){
var alert = UIAlertController(title: title, message: error, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { action in
self.dismissViewControllerAnimated(true, completion: nil)
}))
self.presentViewController(alert, animated: true, completion: nil)
}
I use the function above to show the alert at any point on the viewcontroller.
What does that happen? How can I keep the user on the current viewcontroller?
In your action you are calling self.dismissViewController - in this context "self" is the current view controller, not your alert view, so you are actually requesting the removal of the current view controller.

Resources