You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
During WWDC2022 Apple introduced NavigationStack. A replacement for the previously standard navigation workflow (NavigationView).
On the surface both SwiftUI Router and NavigationStack seem similar in their workflows: you declare routes (or destinations) that control which views to render based on a specific state (i.e. the path). Yet, dive a little deeper and you'll notice there are some major (and important!) differences between the two. This document will highlight and explain some of the differences, helping you better understand the two workflows and to assist you choosing which of the two would better suit your app when it comes to implementing navigation.
First-party vs third-party
As is always the case with software development, it is advised to first check out whether the first-party solution (in this case Apple's NavigationStack) fits your needs before falling to a third-party package (in this case SwiftUI Router).
Closed source vs open source
As obvious as it may seem, it is worth keeping in mind. NavigationStack is part of the SwiftUI framework and is closed source. Meaning we can never be fully sure of what happens behind the scenes nor what kind of magic it's pulling. Not only that, but if there's a bug in NavigationStack's implementation (and SwiftUI has had its fair share of bugs over the years) you'll have to wait for Apple to patch it in a future release.
SwiftUI Router is open source. Meaning you can simply modify it however you wish to your heart's content. Whether to fix a bug or to change its implementation altogether. (Or wait until someone else does it for you 🙂)
Native implementation vs custom implementation
NavigationStack uses UINavigationController on iOS, which has been the default (i.e. 'native') implementation for screen navigation since the first version of iOS. This means - when you use NavigationStack - you get all the system default UI/UX features for free: The toolbar, back button, title (including the transition when scrolling), screen transitions, etc. This guarantees your navigation will be consistent with other iOS apps and will be familiar to your users.
These are the gifts of NavigationStack
With SwiftUI Router you get none of that. You will have to create your own toolbars, your own back buttons, your own screen transitions. Though unlike NavigationStack, you have full control over screen transitions.
Inline vs 'fullscreen'
With NavigationStack the destinations are rendered in said NavigationStack, taking up the entire space (let's call this 'fullscreen'), replacing the default contents.
Routes in SwiftUI Router however are 'inline'. All they really do is render the contents if their path matches that of the Router's state. Routes do no define or dictate the size of their contents. This means Routes can also be applicable for supplemental views like overlays, headers et al.
The state: destinations vs paths
With NavigationStack there are three ways to handle the state. But in essence they all work the same: there's an array of values that all conform to Hashable. This array represents the stack (history) and each value a destination. The first value represents the current destination, the second value the previous destination, and so forth.
Destinations are defined via ViewModifiers.
.navigationDestination(for:User.self){ user inUserScreen(forUser: user)}
With SwiftUI Router the state is just a single string: the path. The reasons and motivations behind the decision of using strings is worth an entire article on its own. But in short: paths are human readable, easy to read and write, easy to share, and can correlate with website URLs.
In SwiftUI Router paths and routes are defined simply with strings. And strings are, of course, prone to typos! Meaning it can take longer (way longer!) to find errors in your code.
func validate(info:RouteInformation)->UUID?{UUID(info.parameters["uuid"]!)}Route("user/:uuid", validator: validate){ uuid in// variable `uuid` is of type `UUID`.UserScreen(userId: uuid)}
Worth noting that both SwiftUI Router and NavigationStack allow you to navigate to a non-existent path: meaning you will potentially have to declare a fallback.
Familiarity
SwiftUI Router works similar to several popular navigation frameworks, i.e.: React Router, Vue Router, Svelte Navigator. It's not too different from countless web frameworks either. If you have any experience with these frameworks then SwiftUI Router should be every easy to get into.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
SwiftUI Router vs NavigationStack
During WWDC2022 Apple introduced
NavigationStack
. A replacement for the previously standard navigation workflow (NavigationView
).On the surface both SwiftUI Router and NavigationStack seem similar in their workflows: you declare routes (or destinations) that control which views to render based on a specific state (i.e. the path). Yet, dive a little deeper and you'll notice there are some major (and important!) differences between the two. This document will highlight and explain some of the differences, helping you better understand the two workflows and to assist you choosing which of the two would better suit your app when it comes to implementing navigation.
First-party vs third-party
As is always the case with software development, it is advised to first check out whether the first-party solution (in this case Apple's NavigationStack) fits your needs before falling to a third-party package (in this case SwiftUI Router).
Closed source vs open source
As obvious as it may seem, it is worth keeping in mind. NavigationStack is part of the SwiftUI framework and is closed source. Meaning we can never be fully sure of what happens behind the scenes nor what kind of magic it's pulling. Not only that, but if there's a bug in NavigationStack's implementation (and SwiftUI has had its fair share of bugs over the years) you'll have to wait for Apple to patch it in a future release.
SwiftUI Router is open source. Meaning you can simply modify it however you wish to your heart's content. Whether to fix a bug or to change its implementation altogether. (Or wait until someone else does it for you 🙂)
Native implementation vs custom implementation
NavigationStack uses
UINavigationController
on iOS, which has been the default (i.e. 'native') implementation for screen navigation since the first version of iOS. This means - when you use NavigationStack - you get all the system default UI/UX features for free: The toolbar, back button, title (including the transition when scrolling), screen transitions, etc. This guarantees your navigation will be consistent with other iOS apps and will be familiar to your users.These are the gifts of NavigationStack
With SwiftUI Router you get none of that. You will have to create your own toolbars, your own back buttons, your own screen transitions. Though unlike NavigationStack, you have full control over screen transitions.
Inline vs 'fullscreen'
With NavigationStack the destinations are rendered in said NavigationStack, taking up the entire space (let's call this 'fullscreen'), replacing the default contents.
Routes in SwiftUI Router however are 'inline'. All they really do is render the contents if their path matches that of the Router's state. Routes do no define or dictate the size of their contents. This means Routes can also be applicable for supplemental views like overlays, headers et al.
The state: destinations vs paths
With NavigationStack there are three ways to handle the state. But in essence they all work the same: there's an array of values that all conform to
Hashable
. This array represents the stack (history) and each value a destination. The first value represents the current destination, the second value the previous destination, and so forth.Destinations are defined via ViewModifiers.
With SwiftUI Router the state is just a single string: the path. The reasons and motivations behind the decision of using strings is worth an entire article on its own. But in short: paths are human readable, easy to read and write, easy to share, and can correlate with website URLs.
Routes are defined using the
Route
views.The Random Users example demonstrates how to setup complex routes in your app.
Type safety(-ish)
Destinations with NavigationStack are type safe(-ish) as they are based on a specific type.
In SwiftUI Router paths and routes are defined simply with strings. And strings are, of course, prone to typos! Meaning it can take longer (way longer!) to find errors in your code.
SwiftUI Router does provide a feature to transform the path (and its placeholders) to a typed value:
Worth noting that both SwiftUI Router and NavigationStack allow you to navigate to a non-existent path: meaning you will potentially have to declare a fallback.
Familiarity
SwiftUI Router works similar to several popular navigation frameworks, i.e.: React Router, Vue Router, Svelte Navigator. It's not too different from countless web frameworks either. If you have any experience with these frameworks then SwiftUI Router should be every easy to get into.
Beta Was this translation helpful? Give feedback.
All reactions