How can I present inside a tab of a UITabBarViewController? - swift

I want to be able to create a TabBarViewController with some tabs and then push into the given tabs
let tabBarViewController = UITabBarController()
let redVc = UIViewController()
redVc.view.backgroundColor = .red
let blueVc = UIViewController()
blueVc.view.backgroundColor = .blue
tabBarViewController.viewControllers = [redVc, blueVc]
This created a tabBarViewController with a red and a blue tab. Now I want to push a yellow VC to the red tab so that I have a yellow and a blue tab.
let yellowVc = UIViewController()
yellowVc.view.backgroundColor = .yellow
tabBarViewController.modalPresentationStyle = .fullScreen
// this doesn't work
viewController.present(tabBarViewController, animated: true)
// must use this
tabBarViewController.viewControllers![0] = yellowVc
What should I do to be able to present in a given tab?

You can setup your UITabbarController in such a way, that each of it's child is a UINavigationController.
All together, you then have the following hierarchy:
UITabbarController
child1 (UINavigationController)
first content ViewController
child2 (UINavigationController)
second content ViewController
Now from within each contentViewController, you can use navigationcontroller.push to push a new viewController to the stack and it will stay inside the tabbar.

Related

only one tab at a time showing up

I am unable to get each tab to show up before it is clicked, I tried setting each one to its own view controller then changing the title that way but it's still not working ( sorry if my formatting is off , this is by first post on here)
thanks
#objc func didTapButton(){
// create and present tab bar controller
let tabBarVC = UITabBarController()
let vc1 = UINavigationController(rootViewController: FirstViewController())
let vc2 = UINavigationController(rootViewController: SecondViewController())
let vc3 = UINavigationController(rootViewController: ThirdViewController())
vc1.title = "My Groups"
vc2.title = "My Events"
vc3.title = "Browse Events"
tabBarVC.setViewControllers([vc1, vc2, vc3], animated: false)
guard let items = tabBarVC.tabBar.items else{
return
}
let images = ["bell", "star", "person"]
for x in 0..<items.count{
items[x].image = UIImage(systemName: images[x])
}
tabBarVC.modalPresentationStyle = .fullScreen
present(tabBarVC, animated: true)
}
Screenshot:
From the doc :
Configuring your tab bar programmatically:
To configure the tab bar associated with a UITabBarController object, configure the view controllers associated with the tab bar controller. The tab bar automatically obtains its items from the tabBarItem property of each view controller associated with the tab bar controller.
To configure tab bar items directly, use the setItems(_:animated:) method of the tab bar itself.
You can not use tabBar.items property directly as you do

TabBar controls the NavigationBar

I added 2 ViewControllers into a TabBar, but now, the TabBar's NavigationBar 'took over' each view's NavigationBar.
I can't set a title for each one of them, I can't add buttons, nothing.
I tried a few solutions to solve it that I found on the internet, but nothing worked.
I need control over the NavigationBar of each one of the views, as I need them to be different, with different title, etc.
This is my TabBar code:
class TabBar: UITabBarController {
let homeVC = HomeVC()
let followingVC = FollowingVC()
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.appColors.mainWhite]
navigationController?.navigationBar.tintColor = UIColor.appColors.mainWhite
navigationItem.setHidesBackButton(true, animated: false)
homeVC.tabBarItem = UITabBarItem(tabBarSystemItem: .topRated, tag: 0)
followingVC.tabBarItem = UITabBarItem(tabBarSystemItem: .contacts, tag: 1)
let tabBarList = [homeVC, followingVC]
viewControllers = tabBarList
}
}
I really need the option to configure each NavigationBar from it's own ViewController, or atleast from the TabBar class.
You should add UINavigationController to each of your ViewControllers not your UITabBarController
First remove the UINavigationController of your TabBar, Either you have done this pragmatically or in the storyboard remove that first.
Second add UINavigationController to you ViewControllers
class TabBar: UITabBarController {
let homeVC = HomeVC()
let followingVC = FollowingVC()
override func viewDidLoad() {
super.viewDidLoad()
homeVC.tabBarItem = UITabBarItem(tabBarSystemItem: .topRated, tag: 0)
followingVC.tabBarItem = UITabBarItem(tabBarSystemItem: .contacts, tag: 1)
let homeNavigationController = UINavigationController(rootViewController: homeVC)
let followingNavigationController = UINavigationController(rootViewController: followingVC)
let tabBarList = [homeNavigationController, followingNavigationController]
viewControllers = tabBarList
}
}
Now if you change any properties like title and barButtons it will reflect accordingly.
Figured it out, the solution is:
The NavigationBar was not the TabBar navigation bar, but the screen that lead to the TabBar (Login Screen for example), I fixed it by hidding the navigation bar of the login screen when transfering to the TabBar controller, now the navigation bar of each view controller is shown and not blocked by the Login Viewcontrolelr navigationbar.

Present viewcontroller with tabbar

I created UITabBarController programmatically in AppDelegate with 4 view controllers(using .xib). When user tap some button on ViewController (VC-A) it present another VC (VC-B) and covered tabbar. So I want to VC-B has a tabbar on the button.
I tried to add VC-B as a child of tabbarcontroller. I tried to .present(vc) and .show(vc) on both: VC-A and VC-A.TabBarController
Creating controllers in AppDelegate:
let controllers = [tabViewController1,tabViewController2,tabViewController3,tabViewController4]
tabBarController.viewControllers = controllers
window?.rootViewController = tabBarController
presenting in VC-A
self.tabBarController?.present(controller, animated: false, completion: nil)
right click and drag from tabbar controller in storyboard to VC-B. that should create a tab on the bottom of your VC-A and VC-B to go back and forth without having to implement any backend code unless you want to animate
The solution is to embed every VC in navigationController and then add to TabBarController.
let vc1 = ViewController1()
let navController1 = UINavigationController(rootViewController: vc1)
navController.isNavigationBarHidden = true
let controllers = [navController1, navController2, navController3, navController4]
tabBarController.viewControllers = controllers
window?.rootViewController = tabBarController
Then call
self.navigationController?.pushViewController(controller, animated:
true)
To diplay VC with tabbar
I will press the red login button at the bottom of the picture and try to log in.
login button => "로그인"
After that, log in.
let moreVC = self.storyboard?.instantiateViewController(withIdentifier: "MoreViewController") as! MoreViewController
moreVC.definesPresentationContext = true
moreVC.modalPresentationStyle = .fullScreen
let navController = UINavigationController(rootViewController: moreVC)
self.present(navController, animated: true, completion: nil)
If the login proceeds without error, the above code will be called to display the screen when the login is completed.
If the flow proceeds as the code above, this screen appears.
The screen shown is not fullscreen, and the tabbar at the bottom is gone. The screen I want is the screen below.
How can I present a tab bar when presenting the screen?

how can I move a data array between tab bar viewControllers when I have navigationControllers involved

I have a tab bar controller and 3 viewControllers connected to it and when I move data between the viewControllers I use the following code, which works perfect:
let secondTab = tabBarController?.viewControllers![1] as! ImageViewController
secondTab.imageArray = images
Now I added navigation to the second viewController with EDITOR->Embed In....so, there is now a navigationController between my ImageViewController and the tabBarController. How can I still get the data to the ImageViewController?
You can try
if let nav = tabBarController?.viewControllers![1] as? UINavigationController {
if let let secondTab = nav.topViewController as? ImageViewController
secondTab.imageArray = images
}
}

Navigation bar not showing with MMDrawerController

I am new to swift and iOS development.
In my project i am loading slidein menu with MMDrawerController, it works fine for slide ,but after initializing MMDrawerController in AppDelegate, by top navigation bar [navigation controller] is not getting displayed. commenting MMDrawer initialization shows the navigation bar and click events are firing proper , following is the navigation initialization code ,
func buildNavigationDrawer()
{
// Instantiate Main.storyboard
let mainStoryBoard:UIStoryboard = UIStoryboard(name:"Main", bundle:nil)
// Create View Controllers
let mainPage:TabBarViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("TabBarViewController") as! TabBarViewController
let leftSideMenu:LeftSideViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("LeftSideViewController") as! LeftSideViewController
let rightSideMenu:RightSideViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("RightSideViewController") as! RightSideViewController
// Wrap into Navigation controllers
let leftSideMenuNav = UINavigationController(rootViewController:leftSideMenu)
let rightSideMenuNav = UINavigationController(rootViewController:rightSideMenu)
// Cerate MMDrawerController
drawerContainer = MMDrawerController(centerViewController: mainPage, leftDrawerViewController: leftSideMenuNav, rightDrawerViewController: rightSideMenuNav)
drawerContainer!.openDrawerGestureModeMask = MMOpenDrawerGestureMode.PanningCenterView
drawerContainer!.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.PanningCenterView
// Assign MMDrawerController to our window's root ViewController
window?.rootViewController = drawerContainer
}
In one of the examples about the MMDrawerController there is this code:
self.drawerController = [[MMDrawerController alloc]
initWithCenterViewController:navigationController....
Try to change your mainPage with a UINavigationController with the rootViewController linked to the TabBarViewController and you should be solve the issue.
DETAIL:
// Wrap into Navigation controllers
let leftSideMenuNav = UINavigationController(rootViewController:leftSideMenu)
let rightSideMenuNav = UINavigationController(rootViewController:rightSideMenu)
let centerMenuNav = UINavigationController(rootViewController: mainPage)
// Cerate MMDrawerController
drawerContainer = MMDrawerController(centerViewController: centerMenuNav, leftDrawerViewController: leftSideMenuNav, rightDrawerViewController: rightSideMenuNav)