Skip to content

Instantly share code, notes, and snippets.

@BrunoCerberus
Last active August 16, 2023 07:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BrunoCerberus/d56033668e8685914db9daa6ab7f5feb to your computer and use it in GitHub Desktop.
Save BrunoCerberus/d56033668e8685914db9daa6ab7f5feb to your computer and use it in GitHub Desktop.
Coordinator with NavigationPath

SwiftUI NavigationPath Coordinator Pattern Documentation

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.

Page

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)
}

Coordinator

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)
        }
    }
}

CoordinatorView

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)
    }
}

HomeView

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")
      }
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment