I'm having this strange issue when I use @StateObject + ForEach and NavigationLink Inside a Form. This breaks bindings in the child view shown.
Consider the following ViewModel class with one published property to use from a View:
When using this view:
And this SubView:
The expected result is when tapping on "Go to child view", navigating
to the subview and tapping "Go back" to return to the main view - it should navigate back using the isActive binding.
But actually, the button "Go Back" Doesn't work.
BUT! If I remove the ForEach element from the form in the main view, the button works again. And it looks like the ForEach breaks everything.
Can anything advise if there is a logical issue with the code or is it a SwiftUI bug?
Any suggestions for a workaround?
Consider the following ViewModel class with one published property to use from a View:
Code Block final class ViewModel: ObservableObject { @Published var isActive = false }
When using this view:
Code Block struct MainView: View { @StateObject var viewModel = ViewModel() var body: some View { NavigationView { Form { NavigationLink ( destination: ChildView(isActive: $viewModel.isActive), isActive: $viewModel.isActive, label: { Text("Go to child view") } ) /* Adding this ForEach causes the NavigationLink above to have a broken binding */ ForEach(1..<4) { Text("\($0)") } } .navigationBarTitle("Test") } } }
And this SubView:
Code Block struct ChildView: View { @Binding var isActive: Bool var body: some View { Button("Go back", action: { isActive = false }) } }
The Issue
The expected result is when tapping on "Go to child view", navigating
to the subview and tapping "Go back" to return to the main view - it should navigate back using the isActive binding.
But actually, the button "Go Back" Doesn't work.
BUT! If I remove the ForEach element from the form in the main view, the button works again. And it looks like the ForEach breaks everything.
Additional findings:
Changing Form to VStack fixes the issue
Using a struct and a @State also fixes the issue
Extracting the ForEach to a subview fixes the issue but
Can anything advise if there is a logical issue with the code or is it a SwiftUI bug?
Any suggestions for a workaround?
Very likely a big flaw in the current implementation of SwiftUI. Better send a feedback to Apple.Can anything advise if there is a logical issue with the code or is it a SwiftUI bug?
Moving the NavigationLink out of Form looks like working in a simple case.Any suggestions for a workaround?
Code Block struct MainView: View { @StateObject var viewModel = ViewModel() var body: some View { NavigationView { ZStack { NavigationLink ( destination: ChildView(isActive: $viewModel.isActive), isActive: $viewModel.isActive, label: { EmptyView() } ) Form { HStack { Text("Go to child view") Spacer() Image(systemName: "chevron.forward") } .contentShape(Rectangle()) .onTapGesture { print(viewModel.isActive) viewModel.isActive = true } ForEach(1..<4) { Text("\($0)") } } } .navigationBarTitle("Test") } } }
There may be other better workarounds, but I could not find any till now.