Ios 在协调器模式中重用视图控制器
我的iOS应用程序中有ViewController的流(Ios 在协调器模式中重用视图控制器,ios,swift,design-patterns,coordinator-pattern,Ios,Swift,Design Patterns,Coordinator Pattern,我的iOS应用程序中有ViewController的流(flow a)。流A相当复杂(取决于具体情况,一些视图控制器会提前显示,或者根本不显示,等等)。为了处理这个问题,我使用了协调器模式 守则(简体): flowcoordinator包含有关如何以及何时使用present()方法显示视图控制器的逻辑。到目前为止还不错 现在我有了第二个流,flowB,与流a大部分不同。除了我想在两者之间共享一个视图控制器之外,我们称之为SharedViewController。这就是事情变得奇怪的地方,因为我不
flow a
)。流A相当复杂(取决于具体情况,一些视图控制器会提前显示,或者根本不显示,等等)。为了处理这个问题,我使用了协调器模式
守则(简体):
flowcoordinator
包含有关如何以及何时使用present()
方法显示视图控制器的逻辑。到目前为止还不错
现在我有了第二个流,flowB
,与流a大部分不同。除了我想在两者之间共享一个视图控制器之外,我们称之为SharedViewController
。这就是事情变得奇怪的地方,因为我不知道如何在两者之间共享这个视图控制器
问题是:我有一个双向通信——协调器将自己设置为它所呈现的视图控制器的协调器&视图控制器调用协调器上的方法作为对用户交互的响应SharedViewController
由两个协调员中的一个管理,不管是哪一个协调员,它都必须以某种方式将信息传递给当前协调员
到目前为止,我发现了两种解决方案,但都不令人满意:
SharedViewController
——这是一个很大的开销,在很大程度上违背了协调器的目的flowcoordinable
,flowcoordinable
。。。在SharedViewController
中,具有多个协调器属性,并在适当的时间调用所有这些属性。还有大量开销、样板代码和对协调员的调用有什么好办法解决这个问题吗?我也遇到了同样的情况,我也不确定最好的解决方案是什么。我有一个viewController,必须在不同的协调员中使用 当给定的viewController本身不需要协调器时,这是正常的。例如,我们将其称为DisplayPopupViewController。 我创建了一个名为CanDisplayPopupProtocol的协议:
protocol CanDisplayPopupProtocol {}
extension CanDisplayPopupProtocol where Self: Coordinator {
func toDisplayPopupViewController() {
let vc = DisplayPopupViewController.instantiate()
navigationController.pushViewController(vc, animated: true)
}
}
然后在Coordinator1中:
extension Coordinator1: CanDisplayPopupProtocol{}
在协调人2中:
extension Coordinator2: CanDisplayPopupProtocol{}
现在,两个协调器都有toDisplayPopupViewController()方法
正如我之前所说的,当我不需要将协调器传递给viewController时,这很好,在这种情况下,DisplayPopupViewController不需要协调器,因为它将被取消,并且不需要任何导航
但是,当需要为viewController分配一个协调器时,它会变得更加复杂。在这种情况下,我传递哪个操作系统作为协调器
在我看来,我发现的解决方案不是很优雅,它是将viewController中的协调器类型更改为协调器协议,因此:
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
}
我确信这不是协议的最佳使用,希望遵循此线程的人能够更好地解决此问题。我还没有在自己的项目中实现这一点,但我目前计划在此基础上改进我们的实现:。它们将协调员注册为UIResponder链的一部分,这样就可以通过Responder链传递消息,而UIViewController不知道协调员的任何详细信息(甚至没有明确的引用)。看起来很有希望,一旦我自己实现了,我会写一个答案。
switch coordinator {
case is Coordinator1:
(coordinator as! Coordinator1).toDisplayPopupViewController()
case is Coordinator2:
(coordinator as! Coordinator2).toDisplayPopupViewController()
default: break
}