问题
Currently, my AppDelegate file contains this code to establish the CustomTabBarController as the rootViewController:
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = CustomTabBarController()
I want my app to always have the CustomTabBarController on the bottom, but I want each tab to have a navigation controller. Here is the code I used to set up my tabBarController:
class CustomTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let vc1 = FirstViewController()
let vc2 = SecondViewController()
let vc3 = ThirdViewController()
viewControllers = [vc1, vc2, vc3]
}
Here is the code I used to set up my FirstViewController:
class ProfileViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: VCCellId, for: indexPath) as! firstVCCell
return cell
}
}
回答1:
When combining a UITabBarController
and UINavigationController
s, the correct way to set that up is to make the UITabBarController
the rootViewController
. Each tab of your UITabBarController
gets its own UINavigationController
. So, if you have 4 tabs, you will create 4 UINavigationControllers
.
See: Adding a Navigation Controller to a Tab Bar Interface
Update
Building off of the code you added in your updated question, create a UINavigationController
for each of your vc1
, vc2
, and vc3
.
class CustomTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let vc1 = UINavigationController(rootViewController: FirstViewController())
let vc2 = UINavigationController(rootViewController: SecondViewController())
let vc3 = UINavigationController(rootViewController: ThirdViewController())
viewControllers = [vc1, vc2, vc3]
}
}
In each of your ViewController
s, set title
to the title you want to be displayed in the navigation bar when that tab is selected:
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
title = "First"
self.navigationController?.navigationBar.titleTextAttributes =
[NSFontAttributeName: UIFont(name: "Chalkduster", size: 27)!,
NSForegroundColorAttributeName: UIColor.black]
}
}
回答2:
I noticed in the comments of the accepted answer that you were wondering where to change the attributes of the navigation bar. If you plan on applying the same customization to each tab you could use the following code within your CustomTabBarController:
class CustomTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
// Tab Bar Customisation
tabBar.barTintColor = .systemPink
tabBar.tintColor = .systemTeal
tabBar.unselectedItemTintColor = .systemGray
tabBar.isTranslucent = false
viewControllers = [
createTabBarItem(tabBarTitle: "Tab 1", tabBarImage: "TabBarImg1", viewController: ViewControllerOne()),
createTabBarItem(tabBarTitle: "Tab 2", tabBarImage: "TabBarImg2", viewController: ViewControllerTwo()),
createTabBarItem(tabBarTitle: "Tab 3", tabBarImage: "TabBarImg3", viewController: ViewControllerThree()),
createTabBarItem(tabBarTitle: "Tab 4", tabBarImage: "TabBarImg4", viewController: ViewControllerFour())
]
}
func createTabBarItem(tabBarTitle: String, tabBarImage: String, viewController: UIViewController) -> UINavigationController {
let navCont = UINavigationController(rootViewController: viewController)
navCont.tabBarItem.title = tabBarTitle
navCont.tabBarItem.image = UIImage(named: tabBarImage)
// Nav Bar Customisation
navCont.navigationBar.barTintColor = .systemRed
navCont.navigationBar.tintColor = .systemBlue
navCont.navigationBar.isTranslucent = false
return navCont
}
}
Personally, I like this approach, because it saves me from repeating code throughout ViewControllers and keeps the tab & nav bar code organized within your custom tab bar class.
If you don't want to use the same tab or nav bar customization throughout the app you can simply customize each one individually how you like within their respective ViewControllers class. However, if every tab is going to have different tab and/or nav attributes Vacawama's answer would most likely be the best approach!
回答3:
You may want to try this:
viewControllers = [vc1, vc2, vc3].map{UINavigationController(rootViewController: $0)}
来源:https://stackoverflow.com/questions/43961766/uinavigationcontroller-and-tabbarcontroller-programmatically-no-storyboards