Reputation: 72
I am experiencing an issue with programmatic navigation in my SwiftUI app. I use a NavigationLink with an isActive binding to navigate to a specific view (EditUser). The first time I toggle the binding (navigateToEditUser) after the app launches, the navigation occurs but immediately goes back. On subsequent activations, it works as expected. This issue repeats every time I restart the app.
Here is the relevant code snippet:
NavigationLink(
destination: EditarUsuario(),
isActive: $navigateToEditUser
) {
EmptyView()
}
The binding (navigateToEditUser) is toggled from within a .sheet like this:
.onNavigateToEditUserData: {
navigateToEditUser = true
}
I have tried:
None of these solutions have resolved the problem. I suspect it might be related to how SwiftUI re-renders the view hierarchy or handles NavigationLink's isActive state during initialization.
What could be causing this behaviour, and how can I ensure consistent navigation without the first activation issue?
Providing more details about full navigation flow:
struct compactNavigation: View {
@EnvironmentObject var state: AppState
var handler: Binding<String?> { Binding(
get: { state.selectedTab },
set: {
let tab = state.selectedTab
if $0 == tab {
state.resetTab.toggle()
print("Reset tab")
} else {
Tutorial.shared.stop()
}
state.selectedTab = $0
}
)}
var body: some View {
TabView(selection: handler) {
NavigationView {
Settings()
}
.tabItem { Label("settings", systemImage: "gearshape.fill") }
.tag(Settings.tag)
}
}
}
struct Settings: View {
var body: some View {
Form {
Section(header: Text("account")) {
NavigationLink(destination:
PlanView()
) {
Text("plan")
.font(.headline)
}
}
}
}
}
struct PlanView: View {
@State var showFilterEditor = false
@State var navigateToEditUser = false
var body : some View {
ScrollView {
VStack {
NavigationLink(
destination: EditarUsuario(),
isActive: $navigateToEditUser
) {
EmptyView()
}
// Rest of the view content...
}
}
.toolbar(content: {
ToolbarItem(placement: .navigationBarTrailing){
Button(action: {
showFilterEditor.toggle()
}, label: {
Label(title: { Text("filter") },
icon: { Image(systemName: "slider.horizontal.3") })
})
}
})
.sheet(isPresented: $showFilterEditor, content: {
NutritionalPlanParameterEditor(
onNavigateToEditUserData: {
navigateToEditUser = true
}
)
})
}
}
Upvotes: 0
Views: 105
Reputation: 343
Combine NavigationLink
with onAppear
If you must use NavigationLink and a binding, reset the binding value in onAppear of the destination view:
NavigationLink(
destination: EditarUsuario().onAppear {
navigateToEditUser = false
},
isActive: $navigateToEditUser
) {
EmptyView()
}
This ensures the navigation state (navigateToEditUser) resets correctly once the destination view appears.
Upvotes: 0