I have got a tab bar controller and in home view controller i have a navigation controller.
-Tab Bar Controller
-- HomeVC
--- VC1 navigation push -> VC2
In VC1 navigation bar is not hidden but inside VC2 is hidden. And im controlling it with viewwillappear and viewwilldisappear.
override func viewWillAppear(_ animated: Bool) {
navigationController?.navigationBar.barStyle = .blackTranslucent
}
override func viewWillDisappear(_ animated: Bool) {
navigationController?.navigationBar.isHidden = false
}
But turning back to the VC1 without swipe, I mean clicking tab bar homeVC icon hides navigation bar. I want to dismiss or pop current viewcontroller and turn back to VC1.
So you can do this by popToRootViewController of UINavigationController. you have to handle this in tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) method of UITabBarDelegate.
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if let rootView = self.viewControllers!["Index of VC1 Controller"] as? UINavigationController {
rootView.popToRootViewController(animated: false)
}
}
Related
I have a tabbar with 3 items. When I click on the second Item on the Tab, I want to present another tabbar which would be like a presentation and maybe the rootViewcontroller but I am unable to do that because it appears like a normal controller above the main tabbar.
I have extended UITabBarControllerDelegate
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if let controller = self.viewControllers?[self.selectedIndex] as? BaseVC {
controller.modalPresentationStyle = .fullScreen
self.present(controller, animated: true, completion: nil)
}
}
BaseVC is the Tabbar controller I am trying to present.
but this does not change the behavior of the item.
I have a customerViewController that has a simple a form. When the user presses submit, a segue is triggered and another view appears. The problem occurs when the user goes back to the customerViewController and finds all of the old information still there. I could simply reset the form fields, but what I'd really like is to find a way to reset the entire VC. From what I've learned so far, the way to reset a vc that hasn't been pushed is to remove it and then add it back.
customerViewController is the initial view controller in a navigation controller which is embedded in a tab bar controller. I have a tabBarController class that is a UITabBarControllerDelegate. This is where I call:
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if item.tag == 2 { //This is the tab with my navigation controller
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "CustomerVCID")
var viewcontrollers = self.navigationController?.viewControllers
viewcontrollers?.removeFirst()
viewControllers?.insert(vc, at: 0)
self.navigationController?.setViewControllers(viewcontrollers!, animated: true)
}
The problem with my code is that navigationController?.viewControllers is nil in the code above. I can reference viewControllers which gives me a list of tab bar viewControllers, but I'm not sure how to get from there to the navigation controller.
I guess my question is, assuming that I'm on the right track, how do I reference the view controllers in my navigation controller?
You can reset your form values in vc inside the viewWillAppear(_:),
class ViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
//clear the textfields, textviews values etc. here.
}
}
It turns out, I was over-complicating things by trying to access navigationController.viewControllers or tabBarController.viewControllers. All I needed was viewControllers which is a property of UITabBarController that contains an array of the controllers associated with each tab:
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if item.tag == 2 { //tab with navigation controller
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vcon = storyboard.instantiateViewController(withIdentifier: "CustomerVCID")
for viewcontroller in viewControllers! {
if let vc = viewcontroller as? UINavigationController {
vc.viewControllers.removeFirst()
vc.viewControllers.insert(vcon, at: 0)
vc.setViewControllers(vc.viewControllers, animated: true)
}
}
}
I have trouble pop all controllers when i do click on tabor item. I have tabbar Controller created programmatically. What i tried to do is... user next methods:
extension TabbarViewController: UITabBarControllerDelegate{
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
self.navigationController?.popViewController(animated: false)
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
self.navigationController?.popViewController(animated: false)
})
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
self.navigationController?.popViewController(animated: false)
return true
}
}
AppDelegate Contains
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
let rootNavController = UINavigationController(rootViewController: TabbarViewController())
UIApplication.shared.keyWindow?.rootViewController = rootNavController
According to your code, your tab bar controller is the root of a navigation controller, so self.navigationController will refer to that navigation controller. This means that the line:
self.navigationController?.popViewController(animated: false)
will try pop the tab bar controller from the navigation controller, but because it is the root, it does nothing.
I assume you have navigation controllers as each of the tabs of the tab bar controller, and you want to pop those navigation controllers to their roots, right?
You should use the viewController parameter to refer to your desired navigation controllers:
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
(viewController as? UINavigationController)?.popToRootViewController(animated: false)
})
}
I have my app setup like this:
NavigationController
|-StartViewController
|-Start2ViewController
|-TabBarController
|-Tab1ViewController
|-Tab2ViewController
I want to hide navigation bar in Tab2ViewController but not in Tab1ViewController. So below is my code for Tab2ViewController:
import UIKit
class Tab2ViewController: ICPVC {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("View Wwill Appear Reached")
self.tabBarController!.navigationController!.setNavigationBarHidden(true, animated: false)
}
}
This does not work and navigation bar appears in both Tab1ViewController and Tab2ViewController, however, if I only switch the tabs' position in Interface builder so that Tab2ViewController is the first Viewcontroller in tabs, then it works and navigation bar is hidden in Tab2ViewController and visible in Tab1ViewController
Can't figure out why?
I have embedded my story board view controllers with the navigation controller. However, I want one view specific controller to not have the navigation bar. How can I do this?
Hide the navigation bar in viewWillAppear.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBarHidden = true
}
Also, make sure you have it appear again when you leave that particular view controller. I usually do this in viewWillDisappear.
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
self.navigationController?.navigationBarHidden = false
}