Hello, I have a HStack with 2 buttons that changes image upon click. The first button does not change on clicking until I click the other button, the second button updates correctly. The difference between the 2 buttons is that the first one’s action depends on the variable ‘museum.favorite’, which is a variable of the class Museum. The second one updates depending on the variable b’s value, which is a state variable declared in the same view.
I have been stuck on this for the past few days and would really appreciate if any one knows the reason behind & a way around this. The reason I want the button to update depending on the value of ‘museum.favorite’ is because I found that if I update according to a state variable declared in the same view (passing the variable as a parameter does not work either), then the image changes back to the default one (“heart” instead of “heart.fill”) soon after I change to another view.
It’s because museum.favorite isn’t being observed by your View. You need to make museum an @StateObject or @ObservedObject with favorite as an @Published property so that SwiftUI will watch it and react to changes you make.
I have tried this already, but adding @Published to favourite gets the error: “Type ‘Museum’ does not conform to protocol ‘Decodable’”. The class Museum is declared as:
class Museum : Identifiable, Decodable, ObservableObject {}.
Take a look at this sample project which is based on some guesses I made about what you might be trying to do. You might want to change the Signing & Capabilities team to your Team before you run it.
Let me know if there is anything you don’t understand.
Thank you so much for the sample project! I’ve run it and it is indeed very similar to what I am trying to do. However, I do have some questions:
Under UpdateFavouriteView, why doesn’t the heart image updates on click? I understand that UpdateFavouriteView is linked under ContentView, and if you start from ContentView → UpdateFavouriteView, then the image changes on click.
Is there a way the heart image in ContentView could be changed directly on click without being directed to UpdateFavouriteView to update it?
These 2 questions are perhaps the same, but this is essentially the part that I am stuck on.
Thank you so much for your time again
Yes, absolutely the favourite can be updated from ContentView rather than going to another screen altogether. I was basing the code on what appeared to be a second view where you were passing in a museum as in a Detail View.
Change you ContentView to this:
struct ContentView: View {
@EnvironmentObject var model: MuseumViewModel
var body: some View {
NavigationView {
List {
ForEach(model.museums) { museum in
HStack {
Text(museum.name)
Spacer()
Image(systemName: museum.favourite ? "heart.fill" : "heart")
.foregroundColor(.red)
.onTapGesture {
model.updateFavourite(museumId: museum.id)
}
}
}
}
.listStyle(PlainListStyle())
.navigationTitle("Museums")
}
}
}