简体   繁体   中英

How do I apply the coordinator pattern to the tabBar?

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:

enter image description here

For quick explanation, only the code that seems necessary is shown. I wonder why my execution result is like this. Please help me

I see two issues:

  1. make parentConordinator weak to prevent retain cycles
  2. 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.

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. }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM