跳到主要内容

Coordinator 模式

问题

Coordinator 解决什么问题?如何实现?

答案

问题背景

ViewController 直接管理导航 → VC 之间强耦合、难以测试、难以复用。

// ❌ VC 耦合导航逻辑
class UserListVC: UIViewController {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let detailVC = UserDetailVC(user: users[indexPath.row])
navigationController?.pushViewController(detailVC, animated: true)
}
}

Coordinator 实现

protocol Coordinator: AnyObject {
var childCoordinators: [Coordinator] { get set }
var navigationController: UINavigationController { get set }
func start()
}

class UserCoordinator: Coordinator {
var childCoordinators: [Coordinator] = []
var navigationController: UINavigationController

init(nav: UINavigationController) {
self.navigationController = nav
}

func start() {
let vm = UserListViewModel()
vm.onSelectUser = { [weak self] user in
self?.showDetail(user: user)
}
let vc = UserListVC(viewModel: vm)
navigationController.pushViewController(vc, animated: true)
}

private func showDetail(user: User) {
let detailVC = UserDetailVC(user: user)
navigationController.pushViewController(detailVC, animated: true)
}
}

SwiftUI 中的简化方案

SwiftUI 用 NavigationStack + 枚举路由替代传统 Coordinator:

enum Route: Hashable {
case userDetail(User)
case settings
}

struct AppCoordinatorView: View {
@State private var path = NavigationPath()

var body: some View {
NavigationStack(path: $path) {
UserListView(path: $path)
.navigationDestination(for: Route.self) { route in
switch route {
case .userDetail(let user):
UserDetailView(user: user)
case .settings:
SettingsView()
}
}
}
}
}

常见面试问题

Q1: Coordinator 和 Router 的区别?

答案:Router 只负责"跳到哪"(URL → VC 映射),Coordinator 更重,负责整个导航流程的协调(创建 VC、传参、管理子 Coordinator)。

相关链接