[英]Reusing View Controller within Coordinator pattern
我的iOS應用程序中有ViewController的流程( Flow A
)。 流程A相當復雜(視情況而定,某些視圖控制器顯示得很早,或者根本沒有顯示,等等)。 為了處理這個問題,我使用了協調器模式。
代碼(簡體):
protocol Coordinator {
func start()
}
protocol FlowACoordinatable {
var coordinator: FlowACoordinator
}
class FlowACoordinator: Coordinator {
private var navigationController: UINavigationController
private var firstVC: FirstViewController
private var secondVC: SecondViewController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() { ... }
func present(_ viewController: (FlowACoordinatable & UIViewController)) {
viewController.coordinator = self
self.navigationController.pushViewController(viewController, animated: true)
}
...
}
class FirstViewController: UIViewController, FlowACoordinatable {
var coordinator: FlowACoordinator?
func buttonTapped() {
self.coordinator?.goToNextStep()
}
}
....
FlowACoordinator
包含有關如何以及何時使用present()
方法呈現視圖控制器的邏輯。 到現在為止還挺好。
現在,我有第二個流程, Flow B
,與流程A大部分不同。除了要在兩者之間共享視圖控制器之外,我們將其稱為SharedViewController
。 這是使事情變得奇怪的地方,因為我對如何在兩者之間共享此視圖控制器沒有真正的好主意。
問題:我有兩種通信方式-協調器將自己設置為它所提供的視圖控制器的協調器,視圖控制器在協調器上調用方法以響應用戶交互。 SharedViewController
是由兩個協調器之一管理的,無論如何它都必須將信息傳遞給當前的協調器。
到目前為止,我發現了兩個解決方案,它們都不令人滿意:
一個僅處理SharedViewController
的附加協調器-這是很多開銷,並且在很大程度上違反了協調器的目的。
在SharedViewController
實現FlowACoordinatable
, FlowBCoordinatable
...,並具有多個協調器屬性,並在適當的時間調用所有這些屬性。 還有很多開銷,樣板代碼和對協調員的調用。
關於如何解決這個問題的任何想法?
我也遇到同樣的情況,我也不知道最好的解決方案是什么。 我有一個必須在不同的協調器中使用的viewController。
當給定的viewController本身不需要協調器時,就可以了。 例如,我們稱其為DisplayPopupViewController。 我創建了一個名為CanDisplayPopupProtocol的協議:
protocol CanDisplayPopupProtocol {}
extension CanDisplayPopupProtocol where Self: Coordinator {
func toDisplayPopupViewController() {
let vc = DisplayPopupViewController.instantiate()
navigationController.pushViewController(vc, animated: true)
}
}
然后在Coordidnator1中:
extension Coordinator1: CanDisplayPopupProtocol{}
在Coordinator2中:
extension Coordinator2: CanDisplayPopupProtocol{}
現在,兩個協調器都具有toDisplayPopupViewController()方法。
正如我之前所說,當我不需要將協調器傳遞給viewController時,這很好,在這種情況下,DisplayPopupViewController不需要協調器,因為它將被關閉並且不需要任何導航。
但是,在這種情況下,當需要將一個協調器分配給viewController時,它將變得更加復雜,我通過的那個協調器呢?
我發現在我看來不是很優雅的解決方案是將viewController中的協調器類型更改為Coordinator協議,所以代替此:
weak var coordinator: Coordinator1?
我將使用:
weak var coordinator: Coordinator?
然后在CanDisplayPopupProtocol中,我將測試我正在處理的協調器,並將正確的協調器分配給viewController,如下所示:
protocol CanDisplayPopupProtocol {}
extension CanDisplayPopupProtocol where Self: Coordinator {
func toDisplayPopupViewController() {
let vc = DisplayPopupViewController().instantiate()
switch self {
case is Coordinator1:
vc.coordinator = self as? Coordinator1
case is Coordinator2:
vc.coordinator = self as? Coordinator2
default: break
}
navigationController.pushViewController(vc, animated: true)
}
}
這並不漂亮,還有另一個缺點。 每次我需要使用一種協調器方法時,都需要在DisplayPopupViewController內測試我使用的是哪種協調器類型。
switch coordinator {
case is Coordinator1:
(coordinator as! Coordinator1).toDisplayPopupViewController()
case is Coordinator2:
(coordinator as! Coordinator2).toDisplayPopupViewController()
default: break
}
我確信這不是協議的最佳用法,希望遵循此線程的人能夠對此問題有更好的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.