NavigationFlowCoordinator 1.1.2

NavigationFlowCoordinator 1.1.2

测试已测试
Lang语言 SwiftSwift
许可证 MIT
发布上次发布2018年12月
SPM支持SPM

Rafal UrbaniakPiotr Czurak维护。



  • 作者:
  • Rafał Urbaniak

NavigationFlowCoordinator

License Pod Version

协调器是指在应用中组织屏幕流程的帮助设计模式。Krzysztof Zabłocki在这篇博客文章中进行了很好的解释。

NavigationFlowCoordinator是这种模式的基本实现,并提供了一些额外有用的功能。

(跳转到安装)

CocoaPods

pod 'NavigationFlowCoordinator'

(跳转到协调器)

Coordinator 协议是表示可以开始和完成某些流的对象的抽象。通常由协调器控制的流部分包括几个 UIViewControllers。`Coordinator` 协议非常简单

public protocol Coordinator: class {
    func start()
    func finish()
}

流程协调器

FlowCoordinatorCoordinator 的基本实现,旨在被特定的协调器实现类继承。 FlowCoordinator 引入了通过子父关系链式连接协调器的功能。任何 FlowCoordinator 都可以通过调用此方法来启动子协调器。

func start(childCoordinator: FlowCoordinator)

它还提供了发送和处理 FlowEvents 的能力。该机制在本文件的后续部分将详细介绍。

导航流程协调器

NavigationFlowCoordinator 是一项流程协调器实现,有助于根据 UINavigationController 控制流程。设计为子类,而不是直接使用。一个非常基础的实现示例可能如下所示

class MoviesListCoordinator: NavigationFlowCoordinator {

    override func createMainViewController() -> UIViewController? {
        let viewController = MoviesListViewController()
        viewController.flowDelegate = self
        return viewController
    }
}

extension MoviesListCoordinator: MovieListFlowDelegate {
    func addNewMovie() {
        // starts child coordinator that handles other part of flow
        start(childCoordinator: MovieCreateOrUpdateCoordinator(movieId: nil))
    }

    func showAbout() {
        // present view controller being part of flow controlled by this coordinator
        push(viewController: AboutViewController())
    }
}

重写 createMainViewController() 方法至关重要,因为这个定义的视图控制器成为协调器的“主要视图控制器”。这意味着一旦主视图控制器从导航控制器中弹出,协调器就结束了其流程。通过直接将新视图控制器推送到导航视图中,或者使用其中一种封装在导航视图控制器上的操作函数(如在 showAbout() 方法中)来展示新视图控制器。当我们想要切换到由其他协调器控制的流程的部分时,我们需要按照 addNewMovie() 方法启动子协调器。通过子父关系链式连接的协调器共享导航控制器实例,除非其中任何一个节点重写了 navigationController 属性。当协调器启动子协调器时,无需存储对其的引用,因为内部机制会为我们保留这个引用。当子协调器结束(无论是通过从导航控制器中弹出主视图控制器,还是调用 finish() 方法)时,引用将释放。

FlowEvent

通常使用委托或块从子协调器传递数据到其父协调器。有时可能会有一系列协协调器,我们可能希望将一些数据从最后一个子协调器传递到几级以上的 Coordinate 中。如果我们使用委托来做这件事,就不可避免地要涉及到内部协调器(位于感兴趣传递数据的协调器之间的协调器)及其委托,即使它们对此类事件毫无兴趣。我们最后得在每个委托中添加新方法,编写代码在来自子协调器的回调上触发这些方法,等等。使用 FlowEvents,这个问题的一个更简单的解决方案。 FlowEvents 机制添加了发送实现 FlowEvent 协议的事件对象的能力。示例

send(flowEvent: MovieUpdatedFlowEvent(movieId: movieId))

事件可以通过重写方法由链中的任何父协协调器处理

override func handle(flowEvent: FlowEvent) -> Bool {
    if let movieUpdatedFlowEvent = flowEvent as? MovieUpdatedFlowEvent, movieUpdatedFlowEvent.movieId == movieId {
        movieDetailsViewController.invalidateMovieData()
    }
    return false
}

协调器处理事件可以防止事件进一步发送。从handle(flowEvent:)函数返回true会导致事件不再向上传递。通过返回false,我们仍然可以处理事件,为父级协调器处理事件留出机会。

示例

在NavigationFlowCoordinatorExample文件夹中,您可以找到使用NavigationFlowCoordinators的示例应用程序。