Skip to content

A SwiftUI navigation framework for iOS, macOS, tvOS, watchOS, and visionOS, based on the coordinator pattern.

License

Notifications You must be signed in to change notification settings

edon2005/CoordinatorX

Repository files navigation



Text changing depending on mode. Light: 'So light!' Dark: 'So dark!'



GitHub Release Static Badge Static Badge Static Badge Static Badge
Static Badge Static Badge Static Badge Static Badge Static Badge


👋 Getting started

There are only 3 steps:

1️⃣ Create an enum for steps in a particular flow.

enum AppRoute: Route {
    case splash
    case onboarding
    case login
    case home
}

2️⃣ Create a Coordinator class for handling steps.

final class AppCoordinator: ViewCoordinator {

    var initialRoute: AppRoute

    init(initialRoute: AppRoute) {
        self.initialRoute = initialRoute
    }

    @MainActor
    func prepareTransition(for route: AppRoute) -> ViewTransitionType {
        switch route {
        case .splash: .root
        case .onboarding: .fullScreen
        case .login: .sheet
        case .home: .multiple(.root, .dismiss)
        }
    }

    @MainActor
    @ViewBuilder
    func prepareView(for route: AppRoute, router: any Router<AppRoute>) -> some View {
        switch route {
        case .splash:
            let viewModel = TemplateViewModel(color: .red, nextStep: .onboarding, router: router)
            TemplateView(viewModel: viewModel)

        case .onboarding:
            let coordinator = OnboardingCoordinator(initialRoute: .screen1, parentRouter: router)
            OnboardingFlow(coordinator: coordinator)
        ....
        }
    }
}

3️⃣ Create a Flow structure to make Coordinator working:

struct AppFlow: DefaultViewFlow {
    var coordinator: AppCoordinator
}

🏁 Using CoordinatorX from App

@main
struct CoordinatorX_ExampleApp: App {

    private let coordinator = AppCoordinator(initialRoute: .splash)

    var body: some Scene {
        WindowGroup {
            AppFlow(coordinator: coordinator)
        }
    }
}

🛠 Installation

Swift Package Manager

See this WWDC presentation about more information how to adopt Swift packages in your app. Specify https://github.com/edon2005/CoordinatorX.git as the CoordinatorX package link.

Manually

If you prefer not to use any of the dependency managers, you can integrate CoordinatorX into your project manually, by downloading the source code and placing the files on your project directory.


🔔 In details

What is Coordinator protocol

var initialRoute: Route from which route a Flow should be started.

func prepareTransition(for route: RouteType) -> TransitionType notify Coordinator how to show a view for route.

func prepareView(for route: RouteType, router: any Router<RouteType>) -> some View prepare View to be showed.

There are 3 types of Coordinators prepared for your app:

  • ViewCoordinator
  • RedirectionViewCoordinator
  • NavigationCoordinator

‼️ Every fullScreen, overlay, sheet has own Context. That means that you can call from them appearing another part of fullScreen, overlay, sheet. And it will be handled by the same Coordinator

ViewCoordinator

It is to present a single root View and the root View can be covered with sheet, fullscreen, overlay or replaced by another View.
ViewCoordinator supports next Transition types:

    case dismiss
    case fullScreen
    case none
    case overlay
    case root
    case set
    case sheet

Transition actions:
dismiss can be applied to dismiss fullScreen, overlay, sheet
fullScreen is applied to cover root View with modal View
none just do nothing
overlay is applied to cover root View with overlay View
root is applied to replace root View with another one. It was created to be used from fullScreen, overlay, sheet
set should be applied to replace View which is presented as fullScreen, overlay, sheet
sheet is applied to cover root View with sheet View

RedirectionViewCoordinator

It is similar to ViewCoordinator, but can be understood as children coordinator. It has identical Transition types plus one additional:

    case parent(ParentRouteType)

Which is used to triger action on parent flow.

NavigationCoordinator

It is to present Navigation Flow. It has identical Transition types as ViewCoordinator plus few additional:

    case pop
    case popToRoot
    case push

Last but not least

Thanks for reading until the end! 🫡