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

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!

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.
[

How can I make a Back button on a Tabbed View App in Xcode

I have already multiple views that are in the tab bar at the bottom. In one of those view controllers (home view), I made a button connecting to another page (feed view) that isn't in the tab bar.
How can I make a back button from the feed view to the home view?
I've searched and I've only found tutorials for single view apps.
Reminder: the feed view isn't in the tab bar.
Add a Navbar then connect the left button(Back Button) to the view controller and do self.dismiss(animated: true, completion: nil) inside of that button action event
or
Just link a button from the view and do
self.dismiss(animated: true, completion: nil)
The way to go from tab view to a separate view use this code inside of the button action to go to a non TabBar view
let objSecondVc = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as? ViewController
objSecondVc!.modalPresentationStyle = .fullScreen
present(objSecondVc!, animated: true, completion: nil)
Then in the seperate View Controller to go back to the TabBar View use
self.dismiss(animated: true, completion: nil)
There is a multiple ways you can do this:
1)
To go to the feed view use present() and then if you want to get back use dismiss()
and the put dismiss function inside of an action of a back button you create in the feed view that you may put it the left upper corner of the view for instance.
2)
You can use NavigationController to go to the feed view and back using the navigation back button.
for me I use the first one because it is more flexible and because I use code instead of storyboard it is easier for me.(Thats just my opinion)

How call a Modal of another Modal

I know there are other topics on this but I can't seem to find out how to implement it.
I have an app that uses only xibs, no storyboards.
I have a modal with a list of items and I need to show another modal with the details of the selected item.
The error found is that the Modal Detail is being opened below the Modal List, requiring a new user click
Below the code to open the Item List
let modalViewController = DependenteListaViewController()
modalViewController.modalPresentationStyle = .overCurrentContext
present(modalViewController, animated: true, completion: nil)
Below the code to open the Item Detail
let modalViewController = DetailViewController ()
modalViewController.modalPresentationStyle = .currentContext
present (modalViewController, animated: false, completion: nil)
What is the correct way to call a modal of another modal?
To present a modal above another modal properly you should:
Get the view controller that presented the first modal
Use that view controller to present the second modal
That way the original presenting view controller will present the second modal above the first.
Swift
firstModalVC.presentingViewController.present(secondModalVC)

How to get rid of navigation controller and segue to a controller before it?

Say I have a storyboard a such logInVC->navViewController->RootVC->restOfStack
If in the rootVC I want to logOut, thereby segueing to logInVC without logInVC becoming a part of my stack then how would I do this. I essentially need to get rid of the navigation controller and its stack entirely, returning to the apps launch page that comes before the navVC.
Was surprised to have trouble finding an answer to this one in Swift, would think this is quite a common problem.
By dismissing the root view controller of your key window, you dismiss all view controllers and go back to youe login vc assuming it's the initial view controller.
UIApplication.sharedApplication().keyWindow?.rootViewController?.dismissViewControllerAnimated(true, completion: nil)
You cannot push a ViewController without NavigationController. But there are few ways to achieve what you need.
Make your Login ViewController as RootViewController.
The closest alternative if you don't want to use navigation controller are ModalView controllers.
To present the controller:
self.presentViewController(controller, animated: true, completion: nil)
To dismiss the controller:
self.dismissViewControllerAnimated(true, completion: {});

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.