首页 > 解决方案 > iOS Swift Coordinator 模式和导航控制器的后退按钮

问题描述

我正在使用模式MVVM+Coordinator。我的每个控制器都是由coordinators. Navigation但是当点击控制器的后退按钮时停止我的协调员的正确方法是什么?

class InStoreMainCoordinator: NavigationCoordinatorType, HasDisposeBag {

    let container: Container

    enum InStoreMainChildCoordinator: String {
        case menu = "Menu"
        case locations = "Locations"
    }

    var navigationController: UINavigationController
    var childCoordinators = [String: CoordinatorType]()

    init(navigationController: UINavigationController, container: Container) {
        self.navigationController = navigationController
        self.container = container
    }

    func start() {
        let inStoreMainViewModel = InStoreMainViewModel()
        let inStoreMainController = InStoreMainController()
        inStoreMainController.viewModel = inStoreMainViewModel

        navigationController.pushViewController(inStoreMainController, animated: true)
    }
}

标签: iosswiftmvvmrx-swiftcoordinator-pattern

解决方案


在阅读了许多关于协调器的文章并看到了一些复杂的想法(如路由器、一些令人费解的魔法和自定义导航控制器委托)之后,我现在要做的是:

View Controller 强烈拥有 Coordinator,如果有的话,Coordinator 对 View Controller 的引用很弱。Coordinator 对其父级的引用很弱,以支持 Coordinator 对象之间通信的责任链。

(责任链设计模式的示例是 iOS 中的响应者链。)

当您在某个协调器上调用 stop 时,视图控制器会从堆栈中弹出,释放并释放协调器。因此,当点击后退按钮并关闭视图控制器时,协调器将被释放。

这对我有用,因为不需要构建额外的基础设施。

最初,我通过构建符合 UINavigationControllerDelegate 协议的 NavigationControllerMutliDelegate 类解决了 UINavigationControllerDelegate 问题。它具有注册/注销逻辑。然后这个对象被传递给每个协调器,以便在视图控制器关闭时通知协调器。NavigationControllerMutliDelegate 是访问者设计模式的一个示例,它有一堆协调器,并且在 View Controller 出现/关闭时,它通过向每个协调器发送一个对象来通知所有协调器。

但是,最后,当看到有多少代码和不必要的复杂性时,我只是选择了拥有 Coordinator 的 View Controller。我只希望对象位于 View Controller 之上,它保留数据提供者、服务、视图模型等,以便 View Controller 更干净。我不想重新发明协调器的推送弹出堆栈并处理这么多所有者问题。就像我想要一些东西来缓解我的生活而不是让它变得更加复杂......


推荐阅读