iOS Coordinator模式,Github代码在此
对于一些界面拥有多VC,或者多VC间跳转,如果都用delegate来通信就会变得很乱
Coordinator模式就是把多VC数据通信放到Coordinator里
首先来个Coordinator,在app launch时会初始化,它拥有一个navigator(举个里的,需要处理页面见跳转)
所有的VC都要准守Coordinating协议
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| enum Event { case buttonTapped }
protocol Coordinator { var navigationController: UINavigationController? { get set } var children: [Coordinator]? { get set } func eventOccurred(with type: Event) func start() }
protocol Coordinating { var coordinator: Coordinator? { get set } }
|
比如VC1里的button事件,发送到Coordinator去处理,目的就是要跳转到VC2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class ViewController: UIViewController, Coordinating { var coordinator: Coordinator? override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = .systemRed title = "Home" let button: UIButton = { let button = UIButton(frame: CGRect(x: 0, y: 0, width: 200, height: 100)) button.backgroundColor = .systemTeal button.center = view.center button.setTitle("Nav to Sec.", for: .normal) button.addTarget(self, action: #selector(didTapButton), for: .touchUpInside) return button }() self.view.addSubview(button) } @objc func didTapButton() { coordinator?.eventOccurred(with: .buttonTapped) }
}
|
MainCoordinator就是来处理这些VC间的事件,这在模式在大型的app中很常见
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class MainCoordinator: Coordinator { var children: [Coordinator]? = nil var navigationController: UINavigationController? func eventOccurred(with type: Event) { switch type { case .buttonTapped: var secondViewController: UIViewController & Coordinating = SecondViewController() secondViewController.coordinator = self navigationController?.pushViewController(secondViewController, animated: true) } } func start() { var vc: UIViewController & Coordinating = ViewController() vc.coordinator = self navigationController?.setViewControllers([vc], animated: false) } }
|
别忘了在appdelegate和scenedelegate里初始化
1 2 3 4 5 6 7 8
| let navVC = UINavigationController() let mainCoordinator = MainCoordinator() mainCoordinator.navigationController = navVC let window = UIWindow(windowScene: windowScene) window.rootViewController = navVC window.makeKeyAndVisible() self.window = window mainCoordinator.start()
|
效果如下: