Lightweight framework for navigation & routing in SwiftUI
Voyager empowers developers to power their SwiftUI-based apps with routing that not only applies to navigation, but also tabs.
In Xcode add the dependency to your project via File > Add Packages > Search or Enter Package URL and use the following url:
https://github.com/bryan-vh/Voyager.git
Once added, import the package in your code:
import Voyager
enum ExampleRoute: Route {
case route1
case route2
case route3(String)
case route4(Int)
}
To start off, create an enum that will represent your set of routes. These can be parameterized by using Swift's enum with associated values.
@StateObject var router = Router<ExampleRoute>(root: .route1)
BaseVoyagerView(router: router) { route in
switch route {
case route1: Route1View()
case route2: Route2View()
// ...
}
}
The simplest of all Voyager views. Use when you don't need navigation or tabs. If you do need navigation or tabs, use the corresponding Voyager view below.
@StateObject var router = Router<ExampleRoute>(root: .route1)
NavVoyagerView(router: router) { route in
switch route {
case route1: Route1View()
case route2: Route2View()
// ...
}
}
NavVoyagerView uses NavigationStack under the hood so you are able to use NavigationLink views as needed in child views.
@StateObject var router = TabRouter<ExampleRoute>(tabs: [.route1, .route2], selected: .route1)
TabVoyagerView(router: router) { route in
switch route {
case route1: Route1View()
case route2: Route2View()
// ...
}
} tabItem: { route in
// Design a label for your tab item
}
TabVoyagerView uses a TabView with an array of NavVoyagerViews under the hood, so navigation works for each tab separately.
struct Route1View: View {
@EnvironmentObject var router: Router<ExampleRoute>
// You can then use the router to push, pop, present modals, or dismiss as needed.
}
You can access a router in any child view of the parent Voyager view.
final class ExampleDeeplinkHandler: DeeplinkHandler<ExampleRoute> {
override func handleDeeplink(url: URL) -> (ExampleRoute, PresentationOption)? {
// Transform the deeplink into a route with a given presentation option.
}
}
By injecting a route-specific DeeplinkHandler into a Router, you will be able to handle any deeplinks that would present some route from that router.