Farhandika
Farhandika

Reputation: 507

Exit Coordinator in Coodinator Pattern in swift

i am a beginner at Coordinator Pattern, so i am trying to create a simple login screen

Load app -> Login screen -> Main Screen

i read an article by Hacking with Swift about Coordinator Pattern and still a bit confuse on how to exit an coordinator.

So how do i exit a coordinator? From what i know, the parent coordinator are consist of the Login Coordinator and Main Screen Coordinator , in order to access the Main Screen Coordinator, you need to clear the child coordinator in the parent coordinator and then add the Main Screen Coordinator. is it correct?

So basically what i want to do is go back to the parent Coordinator and then setup the Min View Coordinator as the parent coordinator child Thanks in advance

Parent Coordinator :

class AppCoordinator:NSObject,CoordinatorExtras {

    
    private(set) var childCoordinators = [Coordinator]()
    private let window:UIWindow
    init(win:UIWindow){
        self.window = win
    }
    func start() {
        let navigationControler = UINavigationController()
        
        let loginCoordinator = LoginCoordinator(navigationController: navigationControler)
        childCoordinators.append(loginCoordinator)
        loginCoordinator.parentCoordinator = self
        loginCoordinator.start()
        
        
        navigationControler.navigationBar.barStyle = .blackTranslucent
        
        window.rootViewController = navigationControler
        window.makeKeyAndVisible()
    }
    
    func userIsValid(_ child:Coordinator?) {
        childDidFinnish(child)
        let navigationControler = UINavigationController()
        let tabBarCoordinator = TabBarCoordinator(navigationController: navigationControler)
        childCoordinators.append(tabBarCoordinator)
        tabBarCoordinator.start()
    }
    
    func childDidFinnish(_ child:Coordinator?) {
        for (idx,coordinator) in childCoordinators.enumerated() {
            if coordinator === child {
                childCoordinators.remove(at: idx)
            }
        }
    }
    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        
            guard let fromVC = navigationController.transitionCoordinator?.viewController(forKey: .from) else { return }
            if navigationController.viewControllers.contains(fromVC) {
                return
            }
            if let homeVC = fromVC as? LoginViewController {
                childDidFinnish(homeVC.coordinator)
            }
    }

}

The childDidFinish function is based on Paul's but i have no idea on how to use it

So this is how i tried to implement it

Login Cordinator:

final class LoginCoordinator:NSObject, Coordinator {
    weak var parentCoordinator:AppCoordinator?
    
    private(set) var childCoordinators: [Coordinator] = []
    private let navigationController : UINavigationController
    private let loginVC = LoginViewController.instantiate()
    
    init (navigationController:UINavigationController) {
        self.navigationController = navigationController
    }
    func start() {
        navigationController.delegate = self
        loginVC.coordinator = self
        navigationController.isNavigationBarHidden = true
        navigationController.pushViewController(loginVC, animated: true)
    }
    func gotoLogin() {
       navigationController.popToRootViewController(animated: true)
    }
    func gotoRegister(){
        let registerVC = RegisterViewController.instantiate()
        registerVC.coordinator = self
        navigationController.pushViewController(registerVC, animated: true)
    }
    func gotoHome() {
        let tabBarCoordinator = TabBarCoordinator(navigationController: navigationController)
        childCoordinators.append(tabBarCoordinator)
        tabBarCoordinator.start()
    }
    func gotoTerdaftar() {
        let terdaftarVC = ListKorperasiViewController()
        terdaftarVC.coordinator = self
        navigationController.pushViewController(terdaftarVC, animated: true)
    }
    func popView() {
        navigationController.popViewController(animated: true)
    }
    //Check if user is login or not
    func userIsLogin() {
        parentCoordinator?.userIsValid(self)
    }
}

Upvotes: 0

Views: 848

Answers (1)

you can add a closure to your child coordinator var finish: (() -> Void)? And associate a value to this closure in your parent coordinator.

let loginCoordinator = LoginCoordinator(navigationController: navigationControler) 
childCoordinators.append(loginCoordinator)
loginCoordinator.finish = { do something like remove coordinator from childCoordinators and start a new coordinator }
loginCoordinator.start()

Upvotes: 1

Related Questions