uptechteam / Coordinator-MVVM-Rx-Example

Example of MVVM-C architecture implemented with RxSwift
564 stars 100 forks source link

How can I implementate tabBarController use Coordinator-RxSwift-MVVM? #4

Closed karta88821 closed 6 years ago

karta88821 commented 6 years ago

I try to follow your example, and use the tabbar as therootviewtroller, but after the run app I found that the navigationbar and the tabbar exist, but the view is black, would like to ask where is the problem, it there something wrong with start () method? thanks!

I have two tabor items in the tabbarViewController:

class TabBarCoordinator: BaseCoordinator<Void> {

    private let window: UIWindow

    init(window: UIWindow) {
        self.window = window
    }

    override func start() -> Observable<Void> {
        // Setup MainNavigation
        let mainNav = UINavigationController()
        mainNav.tabBarItem = UITabBarItem(title: "Product", image: nil, selectedImage: nil)

        // Setup AccountNavigation
        let accountNav = UINavigationController()
        accountNav.tabBarItem = UITabBarItem(title: "Account", image: nil, selectedImage: nil)

        // Setup TabBarViewController
        let tabBarController = UITabBarController()
        tabBarController.viewControllers = [mainNav, accountNav]

        window.rootViewController = tabBarController
        window.makeKeyAndVisible()

        return Observable.never()
    }
}

And TabBarCoordinator is contained MainCoordinator and AccountCoordinator

class MainCoordinator: BaseCoordinator<Void> {

    private let window: UIWindow

    init(window: UIWindow) {
        self.window = window
    }

    override func start() -> Observable<Void> {

        let viewModel = MainViewModel()
        let viewController = MainViewController.initFromStoryboard(name: "Main")

        viewController.viewModel = viewModel

        return Observable.never()
    }
}
arthur-here commented 6 years ago

Hello @karta88821 👋 Thank you for your question. You've done everything right in the TabBarCoordinator! You've only missed one small thing: In order to display MainViewController with a MainCoordinator we should pass a navigation controller crated in the TabBarCoordinator to the MainCoordinator:

class MainCoordinator: BaseCoordinator<Void> {
  init(navigationController: UINavigationController) { 
    self.navigationController = navigationController
  }

  override func start() -> Observable<Void> { 
    ...
    let viewController = MainViewController.initFromStoryboard(name: "Main")
    // ⚠️ IMPORTANT STEP!
    navigationController.pushViewController(viewController, animated: false)
    ...
  }
}

And coordinate(to: ) child coordinators in the TabBarCoordinator:

class TabBarCoordinator: BaseCoordinator<Void> {
  override func start() -> Observable<Void> {
    ...
    let mainNav = UINavigationController()

    // Setup AccountNavigation
    let accountNav = UINavigationController()
    ...
    window.rootViewController = tabBarController
    window.makeKeyAndVisible()

    let mainCoordinator = MainCoordinator(navigationController: mainNav)
    coordinate(to: mainCoordiantor)
      .subscribe()
      .disposed(by: disposeBag)

    let accountCoordinator = MainCoordinator(navigationController: accountNav)
    coordinate(to: accountCoordinator)
      .subscribe()
      .disposed(by: disposeBag)

    return Observable.never()
  }
}

Hope this helps!

karta88821 commented 6 years ago

@arthur-here Thanks for your reply!

shabirjan commented 5 years ago

@arthur-here This implementation is causing memory leak when logging out from Tabbar to login again. Can you provide any tips how to fix it