简体   繁体   中英

Passing data in between controllers using coordinator pattern

I am trying to understand the working of Coordinator Pattern.

Here is my code

import UIKit
import Foundation

class CheckoutCoordinator: Coordinator, ScheduleDelegate {
    
    var childCoordinator: [Coordinator] = [Coordinator]()
    var navigationController: UINavigationController
    
    init(nav: UINavigationController) {
        self.navigationController = nav
    }
    
    func start()  {
        let ctrl = CheckoutController.initFromStoryboard()
        ctrl.coordinator = self
        self.navigationController.pushViewController(ctrl, animated: true)
    }
    
    func openSchedule()  {
        let ctrl = ScheduleController.initFromStoryboard()
        ctrl.delegate = self
        self.navigationController.pushViewController(ScheduleController.initFromStoryboard(), animated: true)
    }
    
    func didSelectTimings(date: NSDate, timings: NSString, distance: Double) {
        
    }

}

From CheckoutController , i go to ScheduleController , do some work which calls its delegate method. The delegate should update some value in CheckoutController and pop scheduleController. I am unable to find any concrete explanation of above senario and how to implement it "properly".

Note that schedule controller has no navigation forward hence no coordinator class for it.

Any guidance will be appreciated

I would not handle the delegate logic in the coordinator. Instead I would move it right into your CheckoutController . So when calling the ScheduleController it would look in your coordinator like this:

func openSchedule(delegate: ScheduleDelegate?)  {
    let ctrl = ScheduleController.initFromStoryboard()
    ctrl.delegate = delegate
    navigationController.pushViewController(ScheduleController.initFromStoryboard(), animated: true)
}

And in your CheckoutController , conform to the ScheduleDelegate delegate:

class CheckoutController: ScheduleDelegate {
    func didSelectTimings(date: NSDate, timings: NSString, distance: Double) {
       // Do your staff   
    }
}

Then in your ScheduleController after calling the delegate method, I would call the coordinator to pop the self(in that case the ScheduleController ).

delegate?.didSelectTimings(date: yourDate, timings: someTiming, distance: distance)
if let checkoutCoordinator = coordinator as? CheckoutCoordinator {
       checkoutCoordinator.popViewController() 
}

The popping logic can be solely in your viewController, but I like to keep the navigation in the Coordinator only. And in your CheckoutCoordinator , or better in your Coordinator (as this function is pretty general), implement the pop function.

extension Coordinator {
     function popViewController(animated: Bool = true) {
         navigationController?.popViewController(animated: animated)
     }
}

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