在 SplitViewController 中替换 UINavigationController 的协调器模式
Coordinator Pattern to replace UINavigationController in SplitViewController
我正在实施 协调器模式 来处理我应用程序中的导航。理论上,当用户选择不同的类别时,我想设置 splitViewController 以用新的类别替换该类别的现有 navigationController。
当应用程序启动协调器时,协调器按预期运行,当我弹出或推送在启动时实现的相同 navigationController
时也工作正常,我唯一的问题是当我尝试替换整个 navigationController
的 splitviewcontroller
.
问题: 添加新的 navigationController 未向用户显示
这是我的实现。
class Coordinator: Navigable, DataCommunicator{
//MARK: - Navigable Conformable
typealias UIController = SplitController
var viewController: UIController
var childCoordinators: [Coordinatable] = []
//MARK: - Root Custom setup
weak var parentCoordinator: RootCoordinator?
//MARK: - Init
init(viewController: UIController) {
self.viewController = viewController
}
func start() {
let categoryNavigationController = CategoryNavigationController()
let categoryNavigationCoordinator = CategoryNavigationCoordinator(viewController: noteNavigationController)
categoryNavigationCoordinator.start()
childCoordinators.append(categoryNavigationCoordinator)
categoryNavigationController.coordinator = self
viewController.viewControllers = [categoryNavigationController]
}
func startSearchCategory() {
childCoordinators.removeLast()
viewController.navigationController?.popToRootViewController(animated: false)
viewController.viewControllers.removeLast()
let searchNavigationController = SearchNavigationController()
let searchCoordinator = SearchNavigationCoordinator(viewController:searchNavigationController)
searchCoordinator.start()
childCoordinators.append(searchCoordinator)
searchNavigationController.coordinator = self
searchCoordinator.parentCoordinator = self
viewController.viewControllers = [searchNavigationController]
}
}
更新:
我想我用不同的方法达到了预期的行为,但我仍然很好奇为什么我不能在 UISplitViewController
中为 masterController 显示不同的 navigationController
并显示它。
但我的方法帮助我的代码更加模块化。我在 Coordinator
协议中添加了以下函数
func stopChild<T: Coordinatable>(coordinator: T, callback: CoordinatorCallBack?)
并实现了如下功能:
override func stopChild<T>(coordinator: T, callback: CoordinatorCallBack?) where T : Coordinatable {
childCoordinators = childCoordinators.filter({[=11=] !== coordinator})
// Calling parent to stop the child coordinator to roll back to the rootController
parentCoordinator?.stopChild(coordinator: self, callback: nil)
}
回滚帮助我实例化了我想要的完整堆栈,而无需尝试为 splitViewController
添加自定义修改代码,而是将整个 splitViewController
替换为与模块 I 对应的代码我正在使用,它更适合一般用途。
因为在我的回叫中,我可以向根协调器发送用户接下来会感兴趣的所需模块。
我正在实施 协调器模式 来处理我应用程序中的导航。理论上,当用户选择不同的类别时,我想设置 splitViewController 以用新的类别替换该类别的现有 navigationController。
当应用程序启动协调器时,协调器按预期运行,当我弹出或推送在启动时实现的相同 navigationController
时也工作正常,我唯一的问题是当我尝试替换整个 navigationController
的 splitviewcontroller
.
问题: 添加新的 navigationController 未向用户显示
这是我的实现。
class Coordinator: Navigable, DataCommunicator{
//MARK: - Navigable Conformable
typealias UIController = SplitController
var viewController: UIController
var childCoordinators: [Coordinatable] = []
//MARK: - Root Custom setup
weak var parentCoordinator: RootCoordinator?
//MARK: - Init
init(viewController: UIController) {
self.viewController = viewController
}
func start() {
let categoryNavigationController = CategoryNavigationController()
let categoryNavigationCoordinator = CategoryNavigationCoordinator(viewController: noteNavigationController)
categoryNavigationCoordinator.start()
childCoordinators.append(categoryNavigationCoordinator)
categoryNavigationController.coordinator = self
viewController.viewControllers = [categoryNavigationController]
}
func startSearchCategory() {
childCoordinators.removeLast()
viewController.navigationController?.popToRootViewController(animated: false)
viewController.viewControllers.removeLast()
let searchNavigationController = SearchNavigationController()
let searchCoordinator = SearchNavigationCoordinator(viewController:searchNavigationController)
searchCoordinator.start()
childCoordinators.append(searchCoordinator)
searchNavigationController.coordinator = self
searchCoordinator.parentCoordinator = self
viewController.viewControllers = [searchNavigationController]
}
}
更新:
我想我用不同的方法达到了预期的行为,但我仍然很好奇为什么我不能在 UISplitViewController
中为 masterController 显示不同的 navigationController
并显示它。
但我的方法帮助我的代码更加模块化。我在 Coordinator
协议中添加了以下函数
func stopChild<T: Coordinatable>(coordinator: T, callback: CoordinatorCallBack?)
并实现了如下功能:
override func stopChild<T>(coordinator: T, callback: CoordinatorCallBack?) where T : Coordinatable {
childCoordinators = childCoordinators.filter({[=11=] !== coordinator})
// Calling parent to stop the child coordinator to roll back to the rootController
parentCoordinator?.stopChild(coordinator: self, callback: nil)
}
回滚帮助我实例化了我想要的完整堆栈,而无需尝试为 splitViewController
添加自定义修改代码,而是将整个 splitViewController
替换为与模块 I 对应的代码我正在使用,它更适合一般用途。
因为在我的回叫中,我可以向根协调器发送用户接下来会感兴趣的所需模块。