You need to enable JavaScript to run this app. SwiftUI EditMode下如何监听List的selection变量变化获取选中计数
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI EditMode下如何监听List的selection变量变化获取选中计数

问题原因

@State 是 SwiftUI 专属的属性包装器,它的真实存储位置独立于当前 View 结构。你自定义的 willSet/didSet 仅在你直接对 selection 变量赋值时触发,SwiftUI 通过 Binding 链路更新 @State 存储的值时会绕开这部分观察者逻辑,和 Set 插入元素的操作无关。

解决方案

以下方案均不需要自定义 EditMode:

  • 方案1:使用 onChange 修饰器(推荐,适配 iOS 14+、macOS 11+ 及更高版本,修改成本最低)
    直接在 List 或其父视图上添加 onChange 监听 selection 的变化即可:
@State var selection = Set<UUID>() 

List(selection: $selection) {
    ForEach(items) { item in
        Text(item.title)
    }
}
.onChange(of: selection) { newValue in
    updateButtonText(count: newValue.count)
}
  • 方案2:通过 @Published 托管状态(适配 iOS 13 等低版本系统)
    把 selection 放到符合 ObservableObject 协议的视图模型中,用 @Published 修饰,此时不管是绑定更新还是手动赋值都会触发属性观察者:
class ListViewModel: ObservableObject {
    @Published var selection = Set<UUID>() {
        didSet {
            updateButtonText(count: selection.count)
        }
    }
    
    // 原有业务逻辑和 updateButtonText 实现
}

在 View 中通过 @ObservedObject 或 @StateObject 持有视图模型,绑定 selection 时使用 $viewModel.selection 即可。

  • 方案3:直接依赖 SwiftUI 自动刷新(仅适用于仅需界面展示计数的场景)
    如果你只需要在 UI 上展示选中数量,不需要触发额外业务逻辑,直接在界面元素中引用 selection.count 即可,SwiftUI 检测到状态变化会自动刷新对应 UI,无需额外监听:
Text("已选中 \(selection.count) 项")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 21:54:03