Передача данных между контроллерами с использованием шаблона координатора

Я пытаюсь понять работу паттерна координатора.

Вот мой код

      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) {
        
    }

}

Из CheckoutController, я иду к ScheduleController, выполните некоторую работу, которая вызывает его метод делегата. Делегат должен обновить некоторое значение в CheckoutController и pop scheduleController. Я не могу найти какого-либо конкретного объяснения вышеупомянутого сенарио и того, как его «правильно» реализовать.

Обратите внимание, что контроллер расписания не имеет навигации вперед, следовательно, для него нет класса координатора.

Любое руководство будет оценено

1 ответ

Решение

Я бы не стал заниматься логикой делегирования в координаторе. Вместо этого я бы переместил его прямо в ваш. Поэтому при вызове в вашем координаторе это будет выглядеть так:

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

И в твоем CheckoutController, соответствовать ScheduleDelegate делегат:

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

Затем в вашем случае после вызова метода делегата я бы вызвал координатора, чтобы он вытолкнул себя (в этом случае ScheduleController).

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

Логика всплывающего окна может быть только в вашем viewController, но я предпочитаю оставлять навигацию только в Координаторе. И в твоем CheckoutCoordinatorили лучше в вашем Coordinator(поскольку эта функция довольно общая), реализуйте функцию pop.

      extension Coordinator {
     function popViewController(animated: Bool = true) {
         navigationController?.popViewController(animated: animated)
     }
}
Другие вопросы по тегам