How can I go back to the initial view controller in Swift? - 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.

Related

Segue push is presenting modally

I created a segue push but it presents the screen modally. Any idea why?
Tried redoing the segue and restarting Xcode but no help there.
After I linked it up via Storyboard, I named the segue in my controller and called perform when button gets tapped.
#IBAction func heyoTapped(_ sender: UIButton) {
performSegue(withIdentifier: "goToFriendList", sender: nil)
}
Select your 1st VC
Add navigation (Editor>Embed In> Navigation Controller.
Make your Navigation controller as initial view controller.
Connect your NextVC with segue (it will Push your new VC by default ), to make sure this you can select segue and make sure the “Kind” is selected as “Show (e.g. Push)”
Now give a name to the segue and do your Perform Segue.
[

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)

iOS Swift: Dismiss View Controller That Was Presented Using "Show Detail"

I have a view controller that is embedded in a navigation controller. I use show detail in storyboard to show it. How would I dismiss this view controller or go back to previous one?
I know back functionality comes automatically when using "Show Detail" but I need to embed this one in a navigation controller, which doesn't allow the back functionality, so I needed to put a "Cancel" bar button, but It's not working. I tried these ways but didn't work:
dismiss(animated: true, completion: nil)
navigationController?.popViewController(animated: true)
self.presentingViewController?.dismiss(animated: true, completion: nil)
You can add an unwind segue from the detail controller to the master controller.
In your master controller, add a method that handles the unwind action:
#IBAction func unwindFromDetail(segue: UIStoryboardSegue) {
}
Then in the storyboard, control drag from detail controller to the "Exit" of master controller, then select the above method.
Give the segue an identifier and perform it!

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

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.

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)