swipe action not popping to previous controller - what am I missing? - swift

I have the UI Gesture Recognizer connected to my swift file and have this code to pop over to the previous controller. However, I'm not having luck atm. what am I missing?
#IBAction func leftswipe(_ sender: Any) {
[navigationController?.popViewController(animated: true)]
}

You need embed first viewController into UINavigationController and use "Show" or "Show Detail" segue`s type.

Try printing navigationController, it must be nil. Are you sure you have the first viewController is embedded in navigation controller and this viewcontroller is in the navigation controller stack? Also I noticed [] brackets in your code. Don't use that in Swift.

Related

Unwind segue through navigation controller

I want have the back button on 'Saved Locations' to unwind segue to the 'Second View Controller', but not sure if I have to do anything different because it is embedded in navigation controller. I have linked the back button to the unwind function already in the storyboard. (ViewController is 'Saved Locations'). Currently, when clicking the back button, nothing happens.
The code below is in the SecondViewController.swift file
#IBAction func fromView(segue: UIStoryboardSegue){
if let sourceViewController = segue.source as? ViewController{
print("hi")
}
}
Segues work in context of the push/modal and popover segues. Your SavedLocations controller is embedded in a UINavigationViewController, but SecondViewController is not child of the same container. It's actually not very clear how you take the user to the SavedLocations from your storyboard screenshot but I'd like to propose embedding both controllers under the same navigation controller as possible. This is the the simplest and the cleanest way, as you don't even have to handle unwind seagues manually at all. "Plain" navigation is handled automatically in backward direction for you (unless you want to pop more than one controller in one go)

Simulating a UINavigationController Pop

I'm using a navigation controller and it works great. However, some custom buttons segue to new ViewControllers (not in the stack) and I don't like the push-type transition animation it uses.
GOAL:
I want to the transitions (described above) to mimic a nav-stack pop transition (where the current view slides to right, revealing the view underneath).
I've successfully simulated a nav-pop using the below code, but then after my buttons and nav-bar back button are super glitchy.
#IBAction func Page2_to_Page1_ButPush(sender: AnyObject) {
var curPage: UIViewController = self.storyboard!.instantiateViewControllerWithIdentifier("Page2_ID") as! UIViewController
var prevPage: UIViewController = self.storyboard!.instantiateViewControllerWithIdentifier("Page1_ID") as! UIViewController
self.navigationController?.pushViewController(prevPage, animated: false)
self.navigationController?.pushViewController(curPage, animated: false)
self.navigationController?.popViewControllerAnimated(true)
}
Can anyone supply a simple way to make my segues simulate a nav-pop?
Details:
X-Code 6.4
Swift
Storyboard
Here's the solution:
iOS Segue - Left to Right -
Simple, easy, works perfect. Add the "SegueFromLeft" class code shown in the link, select the segue you want to present from left, select custom, pointed it at "SegueFromLeft", and the animation is dead on.
Bonus: Even better, it syncs up with the navigation controller, so the nav "Back" button still works.

How can I go back to the initial view controller in Swift?

So I have a login view, after successful login it goes to the first view of a navigation controller, then the user can go deeper to a settings view and then to a logout view. This logout should take the user back to the login view (which is not part of the navigation controller). It works with this code:
let loginViewController = self.storyboard!.instantiateViewControllerWithIdentifier("Login") as? LoginViewController
self.navigationController!.pushViewController(loginViewController!, animated: true)
But the login view displays the navigation bar at the top, which it shouldn't do, maybe there is something other than self.navigationController!.pushViewController that I should be using?
SWIFT: You should use an unwind segue.
First of all, put the following line in your FirstViewController:
#IBAction func prepareForUnwind(segue: UIStoryboardSegue) {
}
The function actually doesn't have any code inside it.
Now, go to your storyboard and create an unwind segue for LogoutViewController by control-dragging from the yellow button to the Exit button. Like this:
Select the unwind segue created for FirstViewController.
Change the segue identifier:
Go to the code of LogoutViewController and just call the unwind segue normally:
self.performSegueWithIdentifier("unwindToViewController1", sender: self)
Swift 4
self.performSegue(withIdentifier: "unwindToViewController1", sender: self)
If you have a Navigation controller, from your your controller use:
self.navigationController?.popToRootViewControllerAnimated(true)
Look into unwind segueing if you are working with storyboards.
You just need to create unwind option in controller, that you want navigate to:
#IBAction func unwindToMe(segue: UIStoryboardSegue){}
Then create segue from storyboard.
And when you need to navigate back, just call the performSegue method with the unwind segue identifier that you just created.
If you want to do it only from code, than you just can write something like:
let loginViewController = self.storyboard?.instantiateViewControllerWithIdentifier("Login")
UIApplication.sharedApplication().keyWindow?.rootViewController = loginViewController
In this case, you will set your app to initial state.
try it
self.view.window?.rootViewController?.dismissViewControllerAnimated(true, completion: nil)
This will get you back to the beginning of the application flow.
Updated to Swift 4 (thanks #javaBeast)
self.view.window?.rootViewController?.dismiss(animated: true, completion: nil)
self.navigationController?.popToRootViewController(animated: true)
is the best option to go to first controller of navigation controller
and then dismiss the navigation controller
I recommend you to make a segue from one ViewController to another, instead of pushing your ViewController like that.
So first, you need to Ctrl + clic from your first ViewController to your login ViewController, and then in the attribute inspector your give it an Identifier.
Then, all you have to do is this :
self.performSegueWithIdentifier("yourIdentifier", sender: self)
Now, for the navigation bar, I suggest you to remove the navigation controller from the login view, and associate it to your first view. It would remove the navigation bar from your login view.

Swift popToRoot not working

This highlighted line is where should popToRoot proceed, after a successful registration it should redirect to Root View Controller. For some reason it's not working for me, literally nothing happens, not even error.
I tried with
self.navigationController?.popToRootViewControllerAnimated(true)
You don't appear to be using navigation controller at all, so I'd wager that self.navigationController is nil.
You could use an unwind segue. So in your root view controller, add a method like so:
#IBAction func unwindToRoot(segue: UIStoryboardSegue) {
print("successfully unwound")
}
Then in your scoreboard scene from which you want to unwind, you can control-drag from the button to the "exit outlet":
When you let go, you can pick the unwind action:
This achieves the "pop to root" sort of functionality, but is not contingent upon using navigation controller.
If you want to perform this unwind programmatically, rather than doing the segue from the button to the exit outlet, do it from the view controller icon to the exit outlet:
Then, select the segue in the document outline and give this segue a unique storyboard id:
Then you can programmatically perform the segue, using the same identifier string:
performSegueWithIdentifier("UnwindToRoot", sender: self)

Dismiss pushed view from within Navigation Controller

I have a Navigation Controller with a View Controller displaying a button. The button is linked to another View Controller using a push segue which automatically adds a top navigation bar with a back button. This all works fine. Pressing the back button slides off the 2nd view and returns to the 1st.
I have a button on the 2nd View Controller, that when pressed runs some code and a delegate call back to the 1st View Controller. Again this works fine.
Now I just need to dismiss the 2nd pushed View from code as if the back button was pressed.
I have tried using dismissModalViewCcontrollerAnimated and dismissViewControllerAnimated, however they both dismiss the whole Navigation Controller which removes view 2 and 1 (returning bak to my main menu).
Whats the correct way to slide off the view.
Obtain a reference to your UINavigationController and call
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
on it.
In Swift it would be calling the method
navigationController?.popViewController(animated: true)
If we use push segue, then use popViewController
#IBAction func backButtonClicked(_ sender: Any) {
self.navigationController?.popViewController(animated: false)
}
In swift you can also call:
self.navigationController?.popToRootViewControllerAnimated(true)
On Objective-C is
[self.navigationController popViewControllerAnimated:YES];
for a jump to the first root controller
[self.navigationController popToRootViewControllerAnimated:YES];
or is a possible move to the specific controller
[self.navigationController popToViewController:(nonnull UIViewController *) animated:(BOOL)];
animation specific animation process of move the controller. If the animation is false the controller will appear without animations.
The UIViewController must be from one which is on the stack.
If NavViewController is used with UIModalPresentationFullScreen then the below line will work
self.navigationController?.dismiss(animated: true, completion: nil)