You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中Binding值仅单次变更:按钮首次点击后其他按钮失效

问题原因与解决方案

问题根源

你的代码中Item结构体的Hashable实现存在关键问题,导致SwiftUI无法正确跟踪视图更新:

  1. Hash值计算不完整:hash(into:)方法未包含id和reel属性,当reel.bid状态切换时,Item的hash值不会变化,SwiftUI的ForEach无法识别元素已更新,对应视图得不到刷新。
  2. 相等判断与Hash逻辑不一致:==方法仅比较id,但hash(into:)未结合id,违反了Hashable协议的核心规则——相等的实例必须拥有相同的hash值。
  3. Reel未实现Hashable:Item的hash计算依赖reel,但Reel未实现Hashable,导致无法正确计算包含reel状态变化的hash值。

修正代码

1. 让Reel实现Hashable

struct Reel: Identifiable, Hashable {
    var id = UUID().uuidString
    var player: AVPlayer
    var bid: Bool
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
        hasher.combine(bid)
    }
    
    static func == (lhs: Reel, rhs: Reel) -> Bool {
        lhs.id == rhs.id && lhs.bid == rhs.bid
    }
}

注:AVPlayer是引用类型,这里仅比较唯一标识id和业务关心的bid状态,忽略player实例本身的差异。

2. 修正Item的Hashable实现

struct Item: Identifiable, Hashable {
    static func == (lhs: Item, rhs: Item) -> Bool {
        lhs.id == rhs.id && lhs.reel == rhs.reel
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
        hasher.combine(chance)
        hasher.combine(name)
        hasher.combine(price)
        hasher.combine(tradeIn)
        hasher.combine(rarityType)
        hasher.combine(description)
        hasher.combine(reel)
    }
    
    var id: String = UUID().uuidString
    var chance: String
    var tradeIn: Int
    var name: String
    var price: String
    var rarityType: String
    var description: String
    var reel: Reel
}

3. 优化TabView的Tag绑定(可选,更规范)

在ReelsView的ForEach中,使用Item自身的id作为tag,避免依赖嵌套的reel.id:

TabView(selection: $currentReel) {
    ForEach($items) { $item in
        ReelsPlayer(reel: $item.reel, currentReel: $currentReel, item: $item)
            .tag(item.id)
    }
}

修复原理

当点击按钮切换item.reel.bid时,Item的hash值会因reel状态变化而更新,ForEach能正确识别元素变更并刷新对应视图,所有按钮的状态和响应逻辑就能正常工作了。

内容的提问来源于stack exchange,提问作者MaxPayne777

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 22:10:29