I am trying to pass a binding to another view that accepts a binding to make changes directly to the model. Whenever I am passing the Binding through a NavigationLink wrapped around the view inside a ForEach, it works fine and any changes made in the view reflects in the model and the view accepting the Binding updates accordingly. However, when I am passing the same binding through a NavigationLink inside a swipeActions block, the model is being updated by the view accepting the Binding but the view is not updating to reflect the changes happened in the model. Theme : Custom Data type in my code. $store.themes[theme] was done by adding a subscript extension to RangeReplaceableCollection
I have a list of themes that is part of my viewModel which is an ObservableObject and my array of Themes is marked with @Published. Consider the code below:
class ThemeStore: ObservableObject {
@Published var themes = [Theme]() {
didSet{
saveToUserDefaults()
}
}
Now in the ThemeManager view, the ThemeStore object is being passed to as an environmentObject. From there, the chosen theme is passed to another View ThemeEditor as a Binding.
struct ThemeManager: View {
@EnvironmentObject var store: ThemeStore
var body: some View {
NavigationStack{
List {
ForEach(store.themes) { theme in
NavigationLink(destination: GameView(game: createNewGame(with: theme))) {
VStack{
//viewBody
}
.swipeActions(edge: .leading) {
NavigationLink {
ThemeEditor(themeToEdit: $store.themes[theme])
} label: {
Label("Edit", systemImage: "slider.vertical.3")
}.tint(.mint)
}
}
} //end of ForEach
The above code works, the navigation link to the ThemeEditor also works passing in the correct binding to the chosen theme. Changes made in the editor also reflects in the model, but the ThemeEditor view is not updating based on the changes made to the model. Changes show only if I go back and return to the view. However, if I use the link to the editor under ForEach like this:
struct ThemeManager: View {
@EnvironmentObject var store: ThemeStore
var body: some View {
NavigationStack{
List {
ForEach(store.themes) { theme in
NavigationLink(destination: ThemeEditor(themeToEdit: $store.themes[theme])) {
VStack{
//viewBody
}
}
} //end of ForEach
then the ThemeEditor view updates/refreshes itself when changes are made to the model from inside the ThemeEditor view.
Why is the view now updating when navigated from inside the swipeActions block even when the binding works and changes are done directly to the model? Am I doing something wrong in passing the data? Do I need to use NavigationView{} instead of NavigationStack{}?