SwiftUI Navigation Destination
There are multiple ways to navigate from one view to another in SwiftUI. Here we look at the differences in subview lifecycle behavior between
- using a boolean
isPresentedbinding; - using a
NavigationPath.
Boolean isPresented
Section titled “Boolean isPresented”The navigation is performed when a binding to a boolean state variable becomes true.
Example
Section titled “Example”struct MainView: View { @State private var isSubviewVisible = false var body: some View { NavigationStack { VStack { Text("Main View") Button { print("Button tapped") isSubviewVisible.toggle() } label: { Text("To subview") } } .navigationDestination(isPresented: $isSubviewVisible) { SubView() } } }}struct SubView: View { var body: some View { VStack { Text("Subview") } }}Lifecycle behavior
Section titled “Lifecycle behavior”- The subview is instantiated when the parent view’s body is evaluated (assuming no conditional branching).
- Visibility is controlled by a boolean binding, but instantiation is not.
- The subview may be created long before navigation actually occurs.
- The same subview instance is reused across repeated navigations.
NavigationPath
Section titled “NavigationPath”The navigation destination is evaluated at the moment the value of the navigation path changes.
Example
Section titled “Example”struct MainView: View { @State private var path = NavigationPath() var body: some View { NavigationStack(path: $path) { VStack { Text("Main View") Button { print("Button tapped") path.append("subview") } label: { Text("To subview") } } .navigationDestination(for: String.self) { name in if name == "subview" { SubView() } } } }}struct SubView: View { var body: some View { VStack { Text("Subview") } }}Lifecycle behavior
Section titled “Lifecycle behavior”- The subview is instantiated only when the navigation path changes.
- Instantiation happens at the moment of navigation.
- When navigating back, the subview is deinitialized and not reused across navigations.
Environment:
Xcode 16.0
Swift 5.10
iOS 18.0