Swift Coordinator模式下复用ViewController的优化方案咨询
解决方案一:抽象通用Coordinator协议
定义一个包含CommonViewController所需行为的抽象协议,让Flow A和Flow B的Coordinator都遵守该协议,这样CommonViewController可以注入这个抽象类型,无需关心具体是哪个Flow的Coordinator。
// 定义通用协议,包含CommonVC需要的方法 protocol CommonFlowCoordinating: AnyObject { func showAnotherViewController() } // Flow A的Coordinator实现 final class CoordinatorA: Coordinator, CommonFlowCoordinating { var navigationController: UINavigationController init(navigationController: UINavigationController = UINavigationController()) { self.navigationController = navigationController } func showAnotherViewController() { // Flow A的专属逻辑:展示对应页面 let vc = AnotherViewControllerA() navigationController.pushViewController(vc, animated: true) } // 启动CommonVC流程 func startCommonFlow() { let commonVC = CommonViewController() commonVC.coordinator = self // 注入抽象协议类型 navigationController.pushViewController(commonVC, animated: true) } } // Flow B的Coordinator实现 final class CoordinatorB: Coordinator, CommonFlowCoordinating { var navigationController: UINavigationController init(navigationController: UINavigationController = UINavigationController()) { self.navigationController = navigationController } func showAnotherViewController() { // Flow B的专属逻辑:展示对应页面 let vc = AnotherViewControllerB() navigationController.pushViewController(vc, animated: true) } func startCommonFlow() { let commonVC = CommonViewController() commonVC.coordinator = self navigationController.pushViewController(commonVC, animated: true) } } // 修改CommonViewController,依赖抽象协议 class CommonViewController: UIViewController { weak var coordinator: CommonFlowCoordinating? // 触发跳转的示例方法 func triggerJump() { coordinator?.showAnotherViewController() } }
优势:
- 符合依赖倒置原则,CommonViewController不再绑定具体Coordinator类型
- 避免代理模式的繁琐配置,逻辑更清晰
解决方案二:闭包回调替代代理
如果不想新增协议,可以用闭包封装回调逻辑,CommonViewController持有闭包,初始化时由对应Coordinator传入具体实现,彻底摆脱代理管理的混乱。
class CommonViewController: UIViewController { // 定义跳转回调闭包 var showAnotherAction: (() -> Void)? // 触发跳转的示例方法 func triggerJump() { showAnotherAction?() } } // CoordinatorA的实现 final class CoordinatorA: Coordinator { var navigationController: UINavigationController init(navigationController: UINavigationController = UINavigationController()) { self.navigationController = navigationController } func startCommonFlow() { let commonVC = CommonViewController() // 绑定Flow A的专属跳转逻辑 commonVC.showAnotherAction = { [weak self] in guard let self = self else { return } let vc = AnotherViewControllerA() self.navigationController.pushViewController(vc, animated: true) } navigationController.pushViewController(commonVC, animated: true) } } // CoordinatorB的实现 final class CoordinatorB: Coordinator { var navigationController: UINavigationController init(navigationController: UINavigationController = UINavigationController()) { self.navigationController = navigationController } func startCommonFlow() { let commonVC = CommonViewController() // 绑定Flow B的专属跳转逻辑 commonVC.showAnotherAction = { [weak self] in guard let self = self else { return } let vc = AnotherViewControllerB() self.navigationController.pushViewController(vc, animated: true) } navigationController.pushViewController(commonVC, animated: true) } }
优势:
- 无需定义代理协议,代码更简洁
- 每个Coordinator直接绑定回调逻辑,避免多代理冲突
解决方案三:协议扩展复用通用逻辑
如果两个Coordinator的跳转逻辑有通用部分(比如导航栏样式设置),可以通过协议扩展抽离通用代码,只让子类实现个性化部分。
protocol CommonFlowCoordinating: AnyObject { var navigationController: UINavigationController { get } func showAnotherViewController() // 钩子方法:子类实现个性化页面创建 func makeSpecificAnotherVC() -> UIViewController } // 协议扩展实现通用逻辑 extension CommonFlowCoordinating { func showAnotherViewController() { // 通用逻辑:比如统一设置导航栏样式 navigationController.navigationBar.tintColor = .systemBlue // 调用钩子方法获取个性化页面 let specificVC = makeSpecificAnotherVC() navigationController.pushViewController(specificVC, animated: true) } } // CoordinatorA实现钩子方法 final class CoordinatorA: Coordinator, CommonFlowCoordinating { var navigationController: UINavigationController init(navigationController: UINavigationController = UINavigationController()) { self.navigationController = navigationController } func makeSpecificAnotherVC() -> UIViewController { return AnotherViewControllerA() } } // CoordinatorB实现钩子方法 final class CoordinatorB: Coordinator, CommonFlowCoordinating { var navigationController: UINavigationController init(navigationController: UINavigationController = UINavigationController()) { self.navigationController = navigationController } func makeSpecificAnotherVC() -> UIViewController { return AnotherViewControllerB() } }
优势:
- 最大化复用通用代码,减少重复实现
- 保留各个Flow的个性化逻辑,扩展性强
内容的提问来源于stack exchange,提问作者manubrio
相关产品推荐
相关产品推荐

