I want to apply the coordinator pattern to the tab bar.
first, my AppCoordinator
class AppCoordinator: Coordinator {
let window: UIWindow?
var navigationController: UINavigationController
var childCoordinator: [Coordinator] = []
var parentCoordinator: Coordinator?
init(_ window: UIWindow?, navigationController: UINavigationController) {
self.window = window
self.navigationController = navigationController
window?.makeKeyAndVisible()
}
func start() {
var tabBarController = setTabBarController()
self.window?.rootViewController = tabBarController
}
func setTabBarController() -> UITabBarController {
let tabBar = UITabBarController()
let firstItem = UITabBarItem(title: nil, image: Image.mainImg, tag: 0)
let secondItem = UITabBarItem(title: nil, image: Image.searchImg, tag: 1)
let thirdItem = UITabBarItem(title: nil, image: Image.likePostImg, tag: 2)
let fourItem = UITabBarItem(title: nil, image: Image.profileImg, tag: 3)
let firstCoordinator = MainCoordinator(navigationController: navigationController)
firstCoordinator.parentCoordinator = self
childCoordinator.append(firstCoordinator)
let firstVC = firstCoordinator.startPush()
firstVC.tabBarItem = firstItem
let secondCoordinator = SearchCoordinator(navigationController: navigationController)
secondCoordinator.parentCoordinator = self
childCoordinator.append(secondCoordinator)
let secondVC = secondCoordinator.startPush()
secondVC.tabBarItem = secondItem
let thirdCoordinator = LikePostCoordinator(navigationController: navigationController)
thirdCoordinator.parentCoordinator = self
childCoordinator.append(thirdCoordinator)
let thirdVC = thirdCoordinator.startPush()
thirdVC.tabBarItem = thirdItem
tabBar.viewControllers = [firstVC, secondVC, thirdVC]
return tabBar
}
}
and my MainCoordinator
class MainCoordinator: baseCoordinator {
func startPush() -> UINavigationController {
let MainVC = MainViewController(viewModel: .init(coordinator: self))
navigationController.setViewControllers([MainVC], animated: true)
return navigationController
}
}
searchVC and likePostVC are the same.
However, my execution result was as follows:
For quick explanation, only the code that seems necessary is shown. I wonder why my execution result is like this. Please help me
CodePudding user response:
I see two issues:
- make parentConordinator
weak
to prevent retain cycles - you are passing the same navigationController to all your tab roots. That cannot work and is probably the reason for the problem you are seeing.
CodePudding user response:
I think you need a coordinator for your tabBarController. And in start of that coordinator you add your child coordinators to your tabBarCoordinator.
I always had login flow before tabBar, and on start of AppCoordinator I initialize login and set appCoordinator.rootViewController to loginCoordinator.rootViewController. This is how I use coordinators with tabBar:
class AppCoordinator() {
func start() {
// Mostly initializing login.
// somehow loginCoordinator triggers coordinatorDelegate.goToTabBar()
}
func goToTabBar() {
tabBarCoordinator = TabBarCoordinator(root: root, dependencies: dependencies)
tabBarCoordinator.coordinatorDelegate = self
tabBarCoordinator.start()
}
}
And here is how I start my TabBarCoordinator:
class TabBarCoordinator {
func start() {
let tabBarController = TabBarController()
let firstCoordinator = //
children.append(firstCoordinator)]
firstCoordinator.start()
let controller1 = UIViewController()
controller1 = firstCoordinator.rootViewController
// Do the same for second..
tabBarController.viewControllers = [controller1, controller2]
rootViewController.show(tabBarController, sender: nil)
}
And here is how to initialize sub coordinators:
class FirstCoordinator {
func start() {
let firstVC = FirstViewController()
let navController = UINavigationController(rootViewController: firstVC)
rootViewController = navController
}
}
I tried to simplify the code, it might not the direct answer you are looking for but i think it will be helpful to understand the pattern. }