I migrated from an ObservableObject to the @Observable macro and I am now experiencing an issue with a simple functionality.
I have an enum Reaction:
enum Reaction: CaseIterable, Identifiable {
case like, dislike, love
var id: Self { self }
var systemImageName: String {
switch self {
case .like: "hand.thumbsup"
case .dislike: "hand.thumbsdown"
case .love: "heart"
}
}
var selectedSystemImageName: String {
systemImageName + ".fill"
}
}
In the viewModel I handle the choice of the user and set the chosen reaction:
@Observable
class ViewModel {
var reaction: Reaction?
func set(_ newReaction: Reaction) async {
// Here goes a DB update
reaction = newReaction == reaction ? nil : newReaction
}
}
And the view is displaying all the cases, you can change the selected reaction or cancel the existing one on tap:
struct ContentView: View {
@State private var viewModel = ViewModel()
var body: some View {
HStack(spacing: 40) {
ForEach(Reaction.allCases) { reaction in
Image(systemName: viewModel.reaction == reaction ? reaction.selectedSystemImageName : reaction.systemImageName)
.font(.largeTitle)
.onTapGesture {
Task {
await viewModel.set(reaction)
}
}
}
}
}
}
It was working fine before migrating to @Observable but now the UI does not reflect the reaction value and I can obtain this:
Of course this is not supposed to be possible…
Any idea why ?