This documentation provides an overview of a SwiftUI implementation that employs the Coordinator pattern. The Coordinator pattern separates navigation logic from view logic, providing a centralized place to handle navigation.
An enumeration representing the different pages or views available in the application.
- home: Represents the home page of the application.
- detail(Movie): Represents the detailed view for a particular movie.
import SwiftUI
enum Page: Hashable {
case home
case detail(Movie)
}
An observable object that handles the application's navigation logic.
- path: Represents the current navigation path.
- homeViewModel: A lazily instantiated view model for the home view.
- push(page: Page): A method to push a new page onto the navigation path.
- build(page: Page) -> some View: A method that returns the appropriate view based on the provided page.
class Coordinator: ObservableObject {
@Published var path = NavigationPath()
lazy var homeViewModel = HomeViewModel()
func push(page: Page) {
path.append(page)
}
@ViewBuilder
func build(page: Page) -> some View {
switch page {
case .home:
HomeView(router: HomeNavigationRouter(), viewModel: homeViewModel)
case let .detail(movie):
let vm = MovieDetailsViewModel(movie: movie)
MovieDetailsView(viewModel: vm)
}
}
}
A SwiftUI view that wraps the application's navigation stack. It uses the Coordinator object to handle navigation and view building.
struct CoordinatorView: View {
@StateObject private var coordinator = Coordinator()
var body: some View {
NavigationStack(path: $coordinator.path) {
coordinator.build(page: .home)
.navigationDestination(for: Page.self) { page in
coordinator.build(page: page)
}
}
.environmentObject(coordinator)
}
}
A SwiftUI view that displays a list of movies. Clicking on a movie navigates the user to its detailed view.
struct HomeView: View {
@EnvironmentObject private var coordinator: Coordinator
private let movies: [Movie] = []
var body: some View {
List(movies) { movie in
Button(action: { coordinator.push(page: .detail(movie)) }) {
Text("Tap to detail")
}
}
}
}