Передача данных между контроллерами с использованием шаблона координатора
Я пытаюсь понять работу паттерна координатора.
Вот мой код
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)
}
}