You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 13:33:06