This is an open-source library to use with SwiftUI. It helps you to do navigation actions with your SwiftUI app.
- Define your navigation routes and make your view conform to NavigationScreen for easy routing
- Stack actions: push, pop, popToRoot
- Modal actions: push sheets, fullScreens, popovers and alerts
- iOS 16.0
- macOS 13.0
- WatchOS 9.0
Use Swift Package Manager to add SwiftUINavigation to your XCode project.
- In Xcode, select File > Add Packages...
- Enter the package URL for this repository SwiftUINavigation.
You can find the full demo example that you can build and run in the folder SwiftUINavigationDemo.
- Create an enum for your app routes and make it conform to the
Routable
protocol. - Define the destination view that the route should navigate to in the property
view
.
import SwiftUINavigation
import SwiftUI
enum AppRoute: Routable {
case demo(_ number: Int)
var id: String {
switch self {
case let .demo(number): "demo_\(number)"
}
}
@MainActor
@ViewBuilder
var view: some View {
switch self {
case let .demo(number): DetailView(number: number)
}
}
}
- Add a
@StateObject
for stack navigator and a modal navigator in your root view that defines the NavigationStack - Add another navigator if you need a sub navigator to manage the modal navigation path separatly
- Set the path for the root NavigationStack to
$navigator.path
- Add modal destinations for sheets, fullscreens, alerts, etc. as needed and let
modalNavigator
handle the presentation. - Pass the navigators as environment objects to the child views
import SwiftUINavigation
import SwiftUI
struct ContentView: View {
@StateObject var navigator = Navigator()
@StateObject var modalNavigator = ModalNavigator()
@StateObject var subNavigator = Navigator()
var body: some View {
NavigationStack(path: $navigator.path) {
DetailView(number: 1)
}
.environmentObject(navigator)
.environmentObject(modalNavigator)
.sheet(item: $modalNavigator.sheetDestination) { route in
modalDestination(route)
}
.fullScreenCover(item: $modalNavigator.fullScreenDestination) { route in
modalDestination(route)
}
.alert(isPresented: $modalNavigator.showAlert, details: modalNavigator.alertDetails)
}
func modalDestination(_ route: Route) -> some View {
NavigationStack(path: $subNavigator.path) {
if let r = route.destination as? AppRoute {
r.view
}
}
.environmentObject(subNavigator)
.environmentObject(modalNavigator)
}
}
- In the views where you want to perform navigation actions, implement the
NavigationScreen
protocol - Add the required navigators as
@EnvironmentObject
variables - Add the navigationDestination for your routes
import SwiftUINavigation
import SwiftUI
struct DetailView: View, NavigationScreen {
@EnvironmentObject var navigator: Navigator
@EnvironmentObject var modalNavigator: ModalNavigator
var body: some View {
....
.navigationDestination(for: AppRoute.self) { route in
route.view
}
}
}
- Inside a View that conforms to
NavigationScreen
you can perform navigation actions as follows
Push, pop, popToRoot from your navigation stack
Button("Root") {
popToRoot()
}
Button("Previous") {
pop()
}
Button("Next") {
push(AppRoute.demo(1))
}
Push sheets, fullscreens, popOvers
Button("Sheet") {
pushSheet(AppRoute.demo(1))
}
Button("Fullscreen") {
pushFullscreen(AppRoute.demo(1))
}
Button("Popover") {
pushPopover(AppRoute.demo(1))
}
Configure and present Alerts
Button("Alert") {
let details = AlertDetails(
title: "Alert",
message: "This is an alert message",
onConfirm: {},
confirmationtitle: "Got it!"
)
pushAlert(details)
}