SwiftUI中ObservableObject模型更新后视图未同步刷新问题
问题原因与解决步骤
1. 错误的Game.Card等价性判断逻辑
你自定义了Game.Card的Equatable实现,仅比较content属性是否相等:
static func == (lhs: Game.Card, rhs: Game.Card) -> Bool { return lhs.content == rhs.content }
这会导致isFaceUp、isMatchedUp等影响UI的属性变更时,SwiftUI的ForEach仍然判定两个卡片实例是相同的,不会触发对应卡片视图的重绘。
修复方案:删除自定义的==方法,让系统自动合成Equatable实现(会自动比较所有存储属性),或手动补充所有需要比较的属性:
static func == (lhs: Game.Card, rhs: Game.Card) -> Bool { return lhs.id == rhs.id && lhs.isFaceUp == rhs.isFaceUp && lhs.content == rhs.content && lhs.isMatchedUp == rhs.isMatchedUp && lhs.isPreviouslySeen == rhs.isPreviouslySeen }
2. 手动发布变更通知的时机错误
你在GameViewModel的choose方法中,提前调用了objectWillChange.send(),此时还没有修改gameController属性:
func choose(_ card: Game.Card) { objectWillChange.send() // 通知发送时属性还未修改 gameController.chooseCard(card) }
@Published属性本身会在值变更后自动发布变更通知,手动提前发送的通知不会携带最新的属性值,导致视图刷新时读取的还是旧数据。
修复方案:删除手动的objectWillChange.send()调用即可:
func choose(_ card: Game.Card) { gameController.chooseCard(card) }
完成以上两处修改后,点击卡片触发isFaceUp属性变更时,会自动触发视图重绘,实现卡片翻转效果。
内容的提问来源于stack exchange,提问作者Alejandro Rosales
相关产品推荐
相关产品推荐

