gpt4 book ai didi

ios - MVVM 协调器和弹出 UIViewController

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:54:26 25 4
gpt4 key购买 nike

我最近开始使用协调器(示例:MVVM with Coordinators and RxSwift)来改进我当前的 MVVM 架构。从 UIViewController 中删除导航相关代码是一个很好的解决方案。

但我在 1 个特定场景中遇到了问题。当默认后退按钮或边缘滑动手势弹出 UIViewController 时,会出现此问题。

使用列表-详细信息界面的快速示例:

列表 UIViewController 由 UINavigationController 中的 ListCoordinator 显示。当点击一个项目时,ListCoordinator 会创建一个 DetailCoordinator,将其注册为子协调器并启动它。 DetailCoordinator 将细节 UIViewController 推送到 UINavigationController,就像每篇 MVVM-C 博客文章所说明的那样。

每篇 MVVM-C 博客文章都未能说明当细节 UIViewController 被默认后退按钮或边缘滑动手势弹出时会发生什么。

DetailCoordinator 应该负责弹出细节 UIViewController,但是 a) 它不知道后退按钮被点击,b) 弹出是自动发生的。此外,ListCoordinator 无法从其子协调器中删除 DetailCoordinator。

一种解决方案是使用自定义后退按钮,它发出点击信号并将其传递给 DetailCoordinator。另一个可能正在使用 UINavigationControllerDelegate。

其他人是如何解决这个问题的?我确定我不是第一个。

最佳答案

我使用 Action用于协调器之间以及协调器和 View Controller 之间的通信。

授权协调器

final class AuthCoordinator: Coordinator {
func startLogin(viewModel: LoginViewModel) {
let loginCoordinator = LoginCoordinator(navigationController: navigationController)

loginCoordinator.start(viewModel: viewModel)
viewModel.coordinator = loginCoordinator

// This is where a child coordinator removed
loginCoordinator.stopAction = CocoaAction { [unowned self] _ in
if let index = self.childCoordinators.index(where: { type(of: $0) == LoginCoordinator.self }) {
self.childCoordinators.remove(at: index)
}
return .empty()
}
}
}

登录协调器

final class LoginCoordinator: Coordinator {
var stopAction: CocoaAction?

func start(viewModel: LoginViewModel) {
let loginViewController = UIStoryboard.auth.instantiate(LoginViewController.self)
loginViewController.setViewModel(viewModel: viewModel)
navigationController?.pushViewController(loginViewController, animated: true)

loginViewController.popAction = CocoaAction { [unowned self] _ in
self.stopAction?.execute(Void())
return .empty()
}
}
}

登录 View Controller

class LoginViewController: UIViewController {
var popAction: CocoaAction?

override func didMove(toParentViewController parent: UIViewController?) {
super.didMove(toParentViewController: parent)
if parent == nil { // parent is `nil` when the vc is popped
popAction?.execute(Void())
}
}
}

因此 LoginViewController 在弹出时执行操作。它的协调器 LoginCoordinator 知道 View 已弹出。它从其父协调器 AuthCoordinator 触发另一个 Action 。父协调器 AuthCoordinatorchildControllers 数组/集合中删除其子 LoginCoordinator

顺便说一句,为什么你需要将子协调器保留在数组中,然后考虑如何删除它们。我尝试了另一种方法,由 View 模型保留的子协调器,一旦 View 模型被释放,协调器也会被释放。为我工作。

但我个人不喜欢这么多的连接,并考虑使用一个协调器对象来处理所有事情的更简单的方法。

关于ios - MVVM 协调器和弹出 UIViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44110768/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com