2022-06-26

iOS开发-Coordi...


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()

效果如下: