About Coordinator Design Pattern
The Coordinator pattern is an architectural design pattern that manages navigation flow and handles the passing of data between view controllers. It helps to decouple view controllers from each other, making the app more maintainable and testable.
Key Features
- Centralized navigation logic
- View controller decoupling
- Hierarchical coordinator structure
- Clean passing of data
- Improved testability
Code Example
// Coordinator pattern example
import UIKit
// Base coordinator protocol
protocol Coordinator: AnyObject {
var childCoordinators: [Coordinator] { get set }
var navigationController: UINavigationController { get set }
func start()
}
// Main application coordinator
class AppCoordinator: Coordinator {
var childCoordinators = [Coordinator]()
var navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let vc = LoginViewController.instantiate()
vc.coordinator = self
navigationController.pushViewController(vc, animated: false)
}
func showMainFlow() {
let mainCoordinator = MainCoordinator(navigationController: navigationController)
childCoordinators.append(mainCoordinator)
mainCoordinator.start()
}
func showProductDetails(product: Product) {
let detailsCoordinator = ProductDetailsCoordinator(navigationController: navigationController, product: product)
childCoordinators.append(detailsCoordinator)
detailsCoordinator.start()
}
func childDidFinish(_ child: Coordinator?) {
for (index, coordinator) in childCoordinators.enumerated() {
if coordinator === child {
childCoordinators.remove(at: index)
break
}
}
}
}
// View controller with coordinator reference
class LoginViewController: UIViewController {
weak var coordinator: AppCoordinator?
static func instantiate() -> LoginViewController {
// Initialize from storyboard or programmatically
return LoginViewController()
}
@IBAction func loginButtonTapped() {
// Perform login logic
coordinator?.showMainFlow()
}
}