Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在协调器模式中重用视图控制器_Ios_Swift_Design Patterns_Coordinator Pattern - Fatal编程技术网

Ios 在协调器模式中重用视图控制器

Ios 在协调器模式中重用视图控制器,ios,swift,design-patterns,coordinator-pattern,Ios,Swift,Design Patterns,Coordinator Pattern,我的iOS应用程序中有ViewController的流(flow a)。流A相当复杂(取决于具体情况,一些视图控制器会提前显示,或者根本不显示,等等)。为了处理这个问题,我使用了协调器模式 守则(简体): flowcoordinator包含有关如何以及何时使用present()方法显示视图控制器的逻辑。到目前为止还不错 现在我有了第二个流,flowB,与流a大部分不同。除了我想在两者之间共享一个视图控制器之外,我们称之为SharedViewController。这就是事情变得奇怪的地方,因为我不

我的iOS应用程序中有ViewController的流(
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
    }