I’m seeing this issue where a Form / NavigationLink set up seems to stop passing through the data on changes.
Expected behavior: Checkmarks should update when you pick a different food.
Observed behavior: You can see the favorite food changing outside the NavigationLink Destination, but not inside.
This setup mirrors a dynamic application where a ForEach is used to display various NavigationLinks in the Form based on parent data. Weirdly enough, this works if you replace Form with VStack, so I’m curious why this isn’t updating.
I have attached two minimum-setup example projects that replicate this issue where the destination of a NavigationLink is not receiving an update when data is changing. One with Binding, one with simpler passed properties.
You can download both sample projects at this stackoverflow link.
Sample Code #2 w/o Bindings
Expected behavior: Checkmarks should update when you pick a different food.
Observed behavior: You can see the favorite food changing outside the NavigationLink Destination, but not inside.
This setup mirrors a dynamic application where a ForEach is used to display various NavigationLinks in the Form based on parent data. Weirdly enough, this works if you replace Form with VStack, so I’m curious why this isn’t updating.
I have attached two minimum-setup example projects that replicate this issue where the destination of a NavigationLink is not receiving an update when data is changing. One with Binding, one with simpler passed properties.
You can download both sample projects at this stackoverflow link.
Sample Code #2 w/o Bindings
Code Block // // ContentView.swift // Form Updating Example // // Created by Sahand Nayebaziz on 12/10/20. // import SwiftUI struct ContentView: View { @State var isPresentingMainView = false @State var favoriteFood: FoodType = .bagel var body: some View { VStack { Button(action: { isPresentingMainView = true }, label: { Text("Present Main View") }) } .fullScreenCover(isPresented: $isPresentingMainView) { MainView(currentFavoriteFood: favoriteFood, onUpdateFavoriteFood: { favoriteFood = $0 }) } } } struct MainView: View { let currentFavoriteFood: FoodType let onUpdateFavoriteFood: (FoodType) -> Void var body: some View { NavigationView { HStack { Spacer() Text(currentFavoriteFood.emoji) .font(.title) .foregroundColor(.secondary) Spacer() NavigationView { Form { List { ForEach(["SomethingRepresentingShowingFood"], id: \.self) { _ in NavigationLink( destination: makeDetail(), label: { Text("Food Randomizer") }) } } } } .navigationViewStyle(StackNavigationViewStyle()) .frame(maxWidth: 350) } .navigationTitle("Main") .navigationBarTitleDisplayMode(.inline) } .navigationViewStyle(StackNavigationViewStyle()) } func makeDetail() -> some View { Form { ForEach(FoodType.allCases) { foodType in Button(action: { onUpdateFavoriteFood(foodType) }, label: { HStack { Text(foodType.emoji) Spacer() if currentFavoriteFood == foodType { Image(systemName: "checkmark") } } }) } } } } enum FoodType: String, Identifiable, CaseIterable { case bagel, pizza, broccoli var id: String { rawValue } var emoji: String { switch self { case .bagel: return "🥯" case .pizza: return "🍕" case .broccoli: return "🥦" } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { Group { ContentView() MainView(currentFavoriteFood: .bagel, onUpdateFavoriteFood: { _ in }) MainView(currentFavoriteFood: .bagel, onUpdateFavoriteFood: { _ in }) .makeDetail() } } }