presentViewController() pops the view behind the last view - ios

I'm trying to perform a transition to another UIViewController in another storyboard but the problem is that the view that I want to display pops behind the view where I'm from.
I know that because my app includes a Snapchat-like navigation between views, so I can drag the view to the left or the right and I can see the view behind.
Here is how I attempt to do that :
#IBAction func account(sender: UIButton) {
if self._isOnline {
self.pageController?.reverseViewControllerAnimated(true)
}
else {
let alertView = UIAlertController(title: "blablablabla", message: "blablablabla", preferredStyle: .Alert)
alertView.addAction(UIAlertAction(title: "No", style: .Cancel, handler: nil))
alertView.addAction(UIAlertAction(title: "Yes", style: .Default, handler: { (alertAction) -> Void in
let storyboard = UIStoryboard(name: "SignUpLogin", bundle: NSBundle.mainBundle())
let vc = storyboard.instantiateInitialViewController() as! UIViewController
self.presentViewController(vc, animated: false, completion: nil)
}))
presentViewController(alertView, animated: true, completion: nil)
}
}
With SignUpLogin that is the name of my second .storyboard file, here I'm in Heart.storyboard.
The action takes place in a UIAlertController, if the user press no, nothing append, if he press yes he's supposed to be redirected to the initial view of my SignUpLogin.storyboard file.
My problem come from the view at the bottom left corner. And if I use the code above in the view at the top right corner, that works ! Why ?
I have no idea of how I can do differently.

I've found the solution to my problem !
#IBAction func account(sender: UIButton) {
if self._isOnline {
self.pageController?.reverseViewControllerAnimated(true)
}
else {
let alertView = UIAlertController(title: Constants.LocalizedJoinOurBand, message: Constants.LocalizedNeedToCreatAnAccount, preferredStyle: .Alert)
alertView.addAction(UIAlertAction(title: Constants.LocalizedNo, style: .Cancel, handler: nil))
alertView.addAction(UIAlertAction(title: Constants.LocalizedYes, style: .Default, handler: { (alertAction) -> Void in
if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
let storyboard = UIStoryboard(name: "SignUpLogin", bundle: NSBundle.mainBundle())
let vc = storyboard.instantiateInitialViewController() as! UIViewController
UIApplication.sharedApplication().keyWindow?.rootViewController = vc
}
}))
presentViewController(alertView, animated: true, completion: nil)
}
}
I don't know why in this case particularly but I have to directly set the rootViewController of my AppDelegate with this line :
UIApplication.sharedApplication().keyWindow?.rootViewController = vc

Related

Why pushviewController does nothing ? Xcode

It is my function I linked to button. It doesn't push to another ViewController. It should work in following way : User clicks button, button creates alert, alert stays in current ViewController or pushes to different existing ViewController. No idea why it is not working - alert shows and nothing happens. Identifier is set and correct.
let alert = UIAlertController(title: "Warning", message: "Aborting adding a routine scheme. Proceed?", preferredStyle: .alert)
alert.addAction(.init(title: "No", style: .cancel, handler: nil))
alert.addAction(.init(title: "Yes", style: .default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
// push to another VC
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "WorkoutViewController") as! WorkoutViewController
self.navigationController?.pushViewController(vc, animated: true)
}))
self.present(alert, animated: true, completion: nil)
Your current ViewController isn't embed in UINavigationController so this line does nothing
self.navigationController?.pushViewController(vc, animated: true)
... because navigationController is nil
If you want to just present ViewController use this
self.present(vc, animated: true, completion: nil)

Controller being pushed twice on iPad screen

I am trying to segue to another controller by clicking on one of presented options on actionsheet. It works just fine on iPhone screens and it's being pushed to appropriate scenes, however issue occurs on iPad. I have been searching a lot for similar issue, but with no success.
#IBAction func actionSheet(_ sender: UIButton) {
let alert = UIAlertController(title: "Please select one of the options", message: nil, preferredStyle: .actionSheet)
let cancelActionButton = UIAlertAction(title: "Cancel", style: .cancel) { action -> Void in }
let recipeActionButton = UIAlertAction(title: "Get The Recipe", style: .default) { action in self.performSegue(withIdentifier: "GetRecipeID", sender: self) }
let facebookActionButton = UIAlertAction(title: "Login with Facebook", style: .default) { action in self.handleCustomFacebookLogin() }
//actions
alert.addAction(cancelActionButton)
alert.addAction(recipeActionButton)
alert.addAction(facebookActionButton)
// support ipad
if let popoverController = alert.popoverPresentationController {
popoverController.sourceView = sender
popoverController.sourceRect = sender.bounds
}
self.present(alert, animated: true, completion: nil)
}
This approach is also not working:
let viewController = UIStoryboard(name: "Detail", bundle: nil).instantiateViewController(withIdentifier: "DetailsVC") as! DetailsViewController
let recipeActionButton = UIAlertAction(title: "Get The Recipe", style: .default, handler: { action in
self.navigationController?.pushViewController(viewcontroller, animated: true)})
I am getting this warning in console when pushing from iPhone:
pushViewController:animated: called on <UINavigationController
0x7fd96a81f800> while an existing transition or presentation is
occurring; the navigation stack will not be updated.
This is not showing when I trigger action from iPad, but new controller is stacked on top.FirstController, SecondController
after clicking on getRecipe/Login button from previous screen.
You could try to perform the segue from another operation
OperationQueue.main.addOperation {
self.performSegue(withIdentifier: "GetRecipeID", sender: nil)
}

Swift - push alert action to show new ViewController

How to show or link to new ViewController when push button on alert?
This is my code
let alert = UIAlertController(title: validateQRObj.responseDescription, message: validateQRObj.productName, preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .default) { (action) -> Void in
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "ProductDetialViewController")
self.present(viewController!, animated: true, completion: nil)
}
alert.addAction(action)
self.present(alert, animated: true, completion: nil)
Control drag from View Controller 1 (The yellow dot) to any where on View Controller 2 and then click on the Segue. Show the Attributes inspector and Under Storyboard Segue identifier name the identifier VC2
If this is the answer you were looking for don't forget to except the answer.
func alert(){
let alertController = UIAlertController(title: "Open View Controller. ", message: "Press Ok to open View Controller number 2.", preferredStyle: UIAlertControllerStyle.alert)
let ok = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: {(action) -> Void in
//The (withIdentifier: "VC2") is the Storyboard Segue identifier.
self.performSegue(withIdentifier: "VC2", sender: self)
})
alertController.addAction(ok)
self.present(alertController, animated: true, completion: nil)
}
For me it doesn't work. I made :
func alert(){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let twop = storyboard.instantiateViewController(withIdentifier: "Accueil") as! Accueil
let alertController = UIAlertController(title: "Open new View !", message: "Clic to ok", preferredStyle: UIAlertControllerStyle.alert)
let ok = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: {(action) -> Void in
self.navigationController?.show(twop, sender: self)
})
alertController.addAction(ok)
self.present(alertController, animated: true, completion: nil)
}
and now it's working !!

Navigate to ViewController from UIAlertController button click

I am quite new to Swift development and I tried referring to the Swift UIAlertController API but couldn't figure out how to navigate to another UIViewController after clicking a button on the UIAlertController.
I would appreciate any pointers, help or a solution to this problem. My code snippet is given below -
#IBAction func showAlert() {
let alertController = UIAlertController(title: "Disclaimer", message: "Disclaimer Text Here", preferredStyle: .Alert)
let declineAction = UIAlertAction(title: "Decline", style: .Cancel, handler: nil)
alertController.addAction(declineAction)
let acceptAction = UIAlertAction(title: "Accept", style: .Default) { (_) -> Void in
let secondVC = ViewController(nibName: "ViewController", bundle: nil)
let navController = UINavigationController(rootViewController: secondVC)
self.presentViewController(navController, animated: true, completion: nil)
}
alertController.addAction(acceptAction)
presentViewController(alertController, animated: true, completion: nil)
}
What I am trying to do here is when a button is clicked the disclaimer AlertController is displayed. If "Decline" button is selected, cancel action is performed and if "Accept" is selected the app should navigate to a Navigation Controller which then allows me to navigate to other ViewControllers using a menu in the application.
Earlier I used the story board to link a button to the NavigationController to traverse to the ViewController I desired. Now I want to do the same programmatically for the AlertController "Accept" Button.
Thank you in advance.
You need to implement the handler block to perform code when an action is selected :
#IBActionfunc showAlert() {
let alertController = UIAlertController(title: "Disclaimer", message: "Disclaimer Text Here", preferredStyle: .Alert)
let declineAction = UIAlertAction(title: "Decline", style: .Cancel, handler: nil)
alertController.addAction(declineAction)
let acceptAction = UIAlertAction(title: "Accept", style: .Default) { (_) -> Void in
let secondVC = SecondViewController(nibName: "SecondView", bundle: nil)
let navController = UINavigationController(rootViewController: secondVC)
self.presentViewController(navController, animated: true, completion: nil)
}
alertController.addAction(acceptAction)
presentViewController(alertController, animated: true, completion: nil)
}
Basically to link the UIAlertViewController button to a UINavigationController's UIViewController we would need to create a manual segue between the UIViewController which has the UIAlertViewController to the UINavigationController.
Please refer to this screen shot to see how to do the above -
Then select the link between the UIViewController and the UINavigationController. Go to the left sidebar and select the Attributes inspector and name the identifier.
Now write the following in your code -
#IBAction func showAlert() {
let alertController = UIAlertController(title: "Disclaimer", message: "Before using this teaching resource, you confirm that you agree:\n1. To obey the law regarding data protection and patient confidentiality.\n2. To us this app professionally and appropriately in clinical settings.\n3. This is for your personal use and you may not modify, distribute, publish, transfer any information obtained from this teaching resource without the developers' permission.\n4. In no event shall the developer be liable to you for any loss arising from your use of this resource.", preferredStyle: .Alert)
let declineAction = UIAlertAction(title: "Decline", style: .Cancel, handler: nil)
let acceptAction = UIAlertAction(title: "Accept", style: .Default) { (_) -> Void in
self.performSegueWithIdentifier("SomeSegue", sender: self) // Replace SomeSegue with your segue identifier (name)
}
alertController.addAction(declineAction)
alertController.addAction(acceptAction)
presentViewController(alertController, animated: true, completion: nil)
}
That's the use of the handler block. You should make your desired action in this block.
Edit: Code
let acceptAction = UIAlertAction(title: "Accept", style: .Default, handler:{ action in
//Write your code here
})
You can use this link as a reference: http://www.appcoda.com/uialertcontroller-swift-closures-enum/

Trying to segue to another view controller using an alert action, in Swift

In my code I have an action sheet that allows a user to either log-in or sign-up. When the user presses either one of these I want to define a handler that will segue them to the login/signup view controller. I'm very new to this so I'm not quite sure what I'm doing wrong but in my code I get an error that the types are not convertible. The code looks like this:
let actionSheet = UIAlertController(title: "Do you have an account?", message: "Please Log-In or Sign-Up", preferredStyle: .ActionSheet)
if let presentationController = actionSheet.popoverPresentationController {
presentationController.sourceView = sender as UIView
presentationController.sourceRect = sender.bounds
}
let dismissHandler = {
(action: UIAlertAction!) in
self.dismissViewControllerAnimated(true, completion: nil)
}
let signupHandler = ({
(ViewController: UIViewController!) in
let signupVC: nextViewController = segue.signupVC as nextViewController
})
let loginHandler = ({
(ViewController: UIViewController!) in
let loginVC: nextViewController = segue.loginVC as nextViewController
})
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: dismissHandler))
actionSheet.addAction(UIAlertAction(title: "Log-In", style: .Default, handler: dismissHandler))
actionSheet.addAction(UIAlertAction(title: "Sign-Up", style: .Default, handler: signupHandler))
presentViewController(actionSheet, animated: true, completion: nil)
}
Any help would be greatly appreciated! Thanks in advance.
I dont know about segues but I normally just present them like this :
let loginVC = LoginViewController()
self.presentViewController(loginVC, animated: true, completion: nil)

Resources