How I could clean UINavigationBar transitions history? - ios

I currently have parental "menu" TableView with UINavigationBar and from each cell there is a segues by reference outlet to 3 similar Views with different information.
In each View there is a buttons to other 2 Views.
With every button's segue opens another View.
The problem:
From every View UINavigationBar's back button returns me to previous View but i tries to make back button to "menu".
Additional Bar Button Item and segue from it makes very close effect but segue animation is not like in UINavigationController.
How I could clean UINavigationBar transitions history in segue to initial View?

You can try pop to root view controller or You can edit navigation controller viewControllers property and remove/add some VC in between.
You can try Unwind Segue mechanism too.

Here are some methods(function) that navigation controller providing for pop operations. They are returning optional UIViewController (intance) from it’s navigation stack, that is popped.
open func popViewController(animated: Bool) -> UIViewController? // Returns the popped controller.
open func popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? // Pops view controllers until the one specified is on top. Returns the popped controllers.
open func popToRootViewController(animated: Bool) -> [UIViewController]?
Here is sample code as a solution to your query::
// if you want to back to root of your app
if let rootNavigationController = self.window?.rootViewController as? UINavigationController {
rootNavigationController.popToRootViewControllerAnimated(true)
}
// But if you want to back to root of your current navigation
if let viewcontroller = self.storyboard?.instantiateViewController(withIdentifier: "NewViewController") as? NewViewController { // or instantiate view controller using any other method
viewcontroller.navigationController?.popToRootViewControllerAnimated(true)
}

Related

Use UINavigationController inside UITabbarController

I'm trying to Use UINavigationController inside a UITabbarController.
this is my Controllers Structure
-UITabbarController(InitialView)
-tabItemOne-DashboardController
-SomeButtons with StoryboardSegue-To-DifferentViewController
-tabItemTwo-OtherController
-tabItemThree-OtherController
Now I want to show the back button when some StoryboardSegue is performed in DashboardViewController.
Let's say I open the app and can see 4 tabbarItems on UITabbarController, in the first tabbar item I have DashboardViewController, in this DashVC I've 3 4 different buttons to show other viewcontrollers. So far so good, everything is working. but once the child viewcontroller from DashVC is on screen, I want to show a back button on the top as UINavigationController do.
I've tried to put the UINavigationController before UITabbarController but its not showing. i've tried to do embed it in DashboardVC but again its not showing.
Do i need to embed seperate UINavigationController with each of childViewControllers of DashboardVC?
Any help is appreciated.
So what you need is this
-UITabbarController(InitialView)
-NavigationController -tabItemOne-DashboardController
-SomeButtons with StoryboardSegue-To-DifferentViewController
-tabItemTwo-OtherController
-tabItemThree-OtherController
and in DashBoardController you need to add this code in
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.navigationBar.isHidden = true
}
override func viewWillDisappear(_ animated: Bool) {
self.navigationController?.navigationBar.isHidden = false
}
this code is to hide the navigation bar in Dashboard and restoring when pushing another view controller so you back button is not hide.
also if you need the same functionality in the others view controller you should embebed in navigation controllers.
is not exactly your case but all navigation Controller are Childs of the UITabBarController that is the initial viewController.

Getting back to main ViewController of the Tab Bar after moving between tabs

I am developing an iOS app in Swift 2.3, XCode 8.0. My app has 4 tabs and to each of the tabs - 4 different View Controllers are connected. Inside the 4 View Controllers I have embedded Navigation controllers.
My requirement is that when a user selects tab 1 -> goes to ViewController 1 -> Next the user can go to 2nd View Controller as there is a navigation controller.
But when the user selects the second tab and then comes back to the first tab, instead of showing the first View Controller that is directly attached to tab 1, the View Controller that was last opened with the back button is shown.
How can I move directly move to the View Controller attached to the first tab?
The embedded navigation controller should automatically keep track of the stack for you regardless of which tab the user is in with the tab bar controller. Make sure each tab has its own navigation controller embedded into it instead of having the entire tab bar controller embedded in one navigation controller.
For example, if you implemented this programmatically:
let viewController1 = UIViewController()
let navigationController1 = UINavigationController()
navigationController1.setViewControllers([viewController1], animated: true)
let viewController2 = UIViewController()
let tabBarController1 = UITabBarController()
tabBarController1.setViewControllers([navigationController1, viewController2], animated: true)
Here the navigationController1 will keep track of which viewController is on top of the stack regardless of where the user is in the tab bar controller.
Thanks, I found the solution -
This works for me -
In my main tab bar viewController, I made it a delegate of both UITabBarController, UITabBarControllerDelegate and then implemented the didSelectViewController method of UITabBarControllerDelegate as below -
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
let index : Int = (tabBarController.viewControllers?.indexOf(viewController))!
let navigationController = viewController as? UINavigationController
navigationController?.popToRootViewControllerAnimated(false)
}

How to navigate from popoverpresentation view controller to another view controller

I have a screen with a navigation controller and it has a button on the nav bar which displays a table (from another view controller) to select things from using pop over presentation, now on clicking any of those items i want to open another view controller a different screen.
BUT if i use navigationController?.pushViewController(tab, animated: true)
the new view controller is displayed within that small pop view itself
and if i use
navigationController?.presentViewController(tab, animated: true)
the navigation bar isn't there on that screen and i cannot go back to the previous screen. How to do it in such a way that i can go back to the screen which first displayed the pop Up list.
If you are using a Storyboard, it's really easy to do. If you're not, then you should. It's very good to use a Storyboard.
Let's call your view controllers these names:
The view controller that can show the popover is called SourceVC
The popover controller is called PopoverVC
The view controller to show when the user selects something from the table view is called NewVC
Add a show segue connecting your SourceVC to your NewVC. Give the segue an identifier.
Add an unwind segue that unwinds from PopoverVC to SourceVC. First, add these methods in your SourceVC:
func unwind(segue: UIStoryboardSegue) {
if let vc = segue.sourceViewController as? PopoverVC {
// get the thing that the user selected and store it somewhere
// perform a segue that shows NewVC
}
}
override func prepareForSegue(segue: UIStoryboardSegue) {
if let vc = segue.destinationViewController as? NewVC {
// pass the thing that the user selected to the NewVC
}
}
Then, select the PopoverVC and control drag it to the "Exit" thingy in SourceVC. And select "unwind:". Give this unwind segue an identifier as well.
When the user selects a row in the table view, just perform the unwind segue and store the thing that the user selected in a class-level variable so that you can pass it to SourceVC.

ios swift - Presenting tab bar controller programatically [duplicate]

This question already has an answer here:
self.tabBarController dismissViewControllerAnimated doesn't work
(1 answer)
Closed 6 years ago.
I'm having a hard time presenting a tab bar controller that is not the root view controller.
I have the current setup:
I want to press a button in my main view controller and be able to present the tab bar controller with the option to go back to the main view controller.
I tried creating a class of type UITabBarViewController, associating it to my Tab Bar Controller and just presenting it but it does not work.
I would like to present the tab bar controller with the favorites tab selected.
What I tried:
let vc = TabBar()
self.presentViewController(vc, animated: true, completion: nil)
You can switch tabs by setting a selected index property of UITabBarController. Like this:
tabBarController.selectedIndex = 1
You don't need to create new view controllers or perform segues if all you want is to switch between the two tabs.
You can do it in tow manner :
using segue :
Drag from button to the tabBarViewController And choose a type (Modal, Push(if your mainViewController is NavBarVC) ...)
from code :
click on your tabBarViewController and go to the attributes inspector and give your VC a storyboard id
and from code :
let mainST = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let VC = mainST.instantiateViewControllerWithIdentifier("idTabBar")
presentViewController(VC, animated: true, completion: nil)
Edit dismiss tabBar
if the tabBar is presented modally,
to dismiss it you have tow choices :
1) using a delegate :
protocol ExitMe {
func exitMe()
}
In the view controller presenter of the tabBar
extension PresenterOfTabBar: ExitMe{
func exitMe(){
dismissViewControllerAnimated(false, completion: nil)
}
}
and in the tabBarViewController define an exitDelegate variable var exitDelegate: ExitMe! and set it's value from the presenter. When the user click a button to exit tabBar you just call exitDelegate.exitMe()
using an unwindFuction when presenting modally using a segue:
in the presenter you define a function like this
#IBAction func unwindFromTabBar(sender: UIStoryboardSegue){
// do what you want here
}
and in the InterfaceBuilder drag from the the button that should exit the tabbar to the exit in the view controller dock then choose the func unwindFromTabBar.
Others solutions may exist (using notification, get the prsenter View controllers ....) you should pick the suitable one...

Swift: miss tab bar after click Back button

I'm new to swift and IOS development. I'm working on a tabbed application(3 views). For example, FirstView, SecondView and ThirdView. FirstView has a button that opens a addNewSession view and the addNewSession view has a Back button that back to the FirstView. The problem is Tab bar disappears after back from the addNewSession view
FirstView to addNewSession view.
#IBAction func toAddNew(sender: AnyObject) {
let addNewSession = self.storyboard?.instantiateViewControllerWithIdentifier("addNewSession") as addNew
self.presentViewController(addNewSession, animated: true, completion: nil)
}
addNewSession view to FirstView
#IBAction func backToPrev(sender: AnyObject) {
println("test1")
let FirstView = self.storyboard?.instantiateViewControllerWithIdentifier("FirstView") as FirstViewController
self.presentViewController(FirstView, animated: true, completion: nil)
}
The problem is your backToPrev method is instantiating a new FirstViewController, which is not the same instance you came from. You are not really going back to the original one, you are showing a new one. This is not what you want.
The proper way to do this is to embed the FirstViewController in a navigation controller, then push the addNew controller onto it. When you use a nav controller, you get the Back behavior for free.
Hopefully you are using a storyboard? Select your FirstViewController, go to the Editor menu and choose Embed in Navigation Controller.
In your toAddNew, instead of presentViewController use self.navigationController.pushViewController to push your addNew controller.
There's an even easier way to do this last step, using segues. You control drag in the storyboard from your button in FirstViewController to the addNew controller and create a Show segue. This will automatically show your addNew controller when the button is touched. With this approach, you will want to remove your toAddNew IBAction and the connection since it's redundant.

Resources