ImperativeNavigation

main

SwiftUI Imperative Navigation Example
ahmdmhasn/swiftui-imperative-navigation

SwiftUI Imperative Navigation

CI Status License Swift Version Platforms

A powerful and lightweight Swift package for managing navigation in SwiftUI apps using an imperative, coordinator-based approach. Build complex navigation flows with clean, testable, and maintainable code.

๐Ÿ“– Read the full article on Medium

โœจ Features

  • ๐ŸŽฏ Imperative Navigation API - Control navigation programmatically from coordinators or view models
  • ๐Ÿ“ฑ Multiple Presentation Styles - Support for push, sheet, and full-screen cover presentations
  • ๐Ÿ—๏ธ Coordinator Pattern - Decouple navigation logic from views for better architecture
  • โœ… Type-Safe - Compile-time safety for navigation parameters
  • ๐Ÿงช Testable - Mock coordinators and test navigation flows easily
  • ๐Ÿ”„ State Management - Share state across navigation flows seamlessly
  • ๐Ÿ“ฆ Lightweight - Minimal dependencies, just SwiftUI

๐Ÿ“Œ Why Imperative Navigation?

While SwiftUI promotes declarative navigation with NavigationStack and NavigationLink, complex navigation flows can become challenging to manage. Imperative navigation offers:

  • โœ… Separation of Concerns - Navigation logic lives outside of views
  • โœ… Enhanced Testability - Test navigation flows independently from UI
  • โœ… Complex Flows Made Simple - Handle multi-step processes, conditional navigation, and dynamic routing
  • โœ… Single Source of Truth - Centralized navigation state management
  • โœ… Better Code Organization - Clear responsibility boundaries between views and navigation

๐Ÿž๏ธ Screenshot

๐Ÿ“ฆ Installation

Swift Package Manager

Add the package to your project using Xcode:

  1. File โ†’ Add Package Dependencies
  2. Enter the repository URL:
    https://github.com/ahmdmhasn/swiftui-imperative-navigation.git
    
  3. Select the version and add to your target

Or add it to your Package.swift:

dependencies: [
    .package(url: "https://github.com/ahmdmhasn/swiftui-imperative-navigation.git", from: "1.0.0")
]

Requirements

  • iOS 16.0+ / watchOS 9.0+ / tvOS 16.0+ / visionOS 1.0+
  • Xcode 16.0+
  • Swift 6.0+

๐Ÿš€ Quick Start

1. Create a Navigation Controller

@MainActor
final class AppCoordinator {
    let navigationController = NavigationController()

    func showDetail(_ item: Item) {
        navigationController.push(DetailView(item: item))
    }

    func showSettings() {
        navigationController.sheet(SettingsView())
    }

    func showConfirmation() {
        navigationController.present(ConfirmationView())
    }
}

2. Set Up Your Root View

@main
struct MyApp: App {
    @StateObject private var coordinator = AppCoordinator()

    var body: some Scene {
        WindowGroup {
            NavigationView(
                controller: coordinator.navigationController,
                root: {
                    HomeView(coordinator: coordinator)
                }
            )
        }
    }
}

3. Navigate From Your Views

struct HomeView: View {
    let coordinator: AppCoordinator

    var body: some View {
        VStack {
            Button("Show Detail") {
                coordinator.showDetail(selectedItem)
            }

            Button("Show Settings") {
                coordinator.showSettings()
            }
        }
    }
}

๐Ÿ“– API Reference

NavigationController

The central controller for managing navigation:

@MainActor
public final class NavigationController: ObservableObject {
    // Push a view onto the navigation stack
    public func push<V: View>(_ view: V)

    // Pop the top view from the stack
    public func pop()

    // Pop all views and return to root
    public func popToRoot()

    // Present a view as a full-screen cover
    public func present<V: View>(_ view: V)

    // Present a view as a sheet modal
    public func sheet<V: View>(_ view: V)

    // Dismiss the current modal (sheet or full-screen)
    public func dismiss()
}

๐Ÿ’ก Example App

Check out the comprehensive example app included in the repository. It demonstrates:

  • ๐Ÿ›’ E-commerce shopping flow with product catalog
  • ๐Ÿ“ฆ Product details with reviews and ratings
  • ๐Ÿ›๏ธ Shopping cart with sheet presentation
  • ๐Ÿ’ณ Multi-step checkout process
  • โœ… Order confirmation with full-screen cover
  • ๐Ÿ”„ Complex navigation flows and state management

View the example code โ†’

๐Ÿงช Testing

The package includes comprehensive unit tests for the navigation controller. The coordinator pattern makes your navigation logic highly testable:

@MainActor
final class MockAppCoordinator: AppCoordinator {
    var didShowDetail = false
    var didShowSettings = false

    override func showDetail(_ item: Item) {
        didShowDetail = true
    }

    override func showSettings() {
        didShowSettings = true
    }
}

// Test your view models or coordinators
func testNavigation() {
    let coordinator = MockCoordinator()
    coordinator.showDetail(item)
    XCTAssertTrue(coordinator.didShowDetail)
}

๐Ÿค Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please read our contribution guidelines before submitting a PR.

๐Ÿ“œ License

This project is licensed under the MIT License. See the LICENSE file for details.

๐Ÿ‘จโ€๐Ÿ’ป Author

Ahmed M. Hassan

๐ŸŒŸ Support

If you find this project helpful:

  • โญ Star the repository
  • ๐Ÿฆ Share on social media
  • ๐Ÿ“ Write about it
  • ๐Ÿ’ฌ Provide feedback and suggestions

๐Ÿ™ Acknowledgments

Thanks to the SwiftUI community for inspiration and feedback on navigation patterns.

Description

  • Swift Tools 6.0.0
View More Packages from this Author

Dependencies

  • None
Last updated: Sun Jan 18 2026 10:07:51 GMT-1000 (Hawaii-Aleutian Standard Time)