SwiftUI问题:Mac端Table中的Toggle无法显示模型值
SwiftUI Table中Toggle状态不更新的解决方法
问题根源
你的代码中Toggle能修改Item的value值但无法同步显示状态,核心原因:
Item是ObservableObject引用类型,当它的@Published var value变化时,TableViewProvider里的@Published var tableViewDataList数组本身并未发生改变(数组元素的引用地址未变),因此SwiftUI不会触发视图刷新。- 手动创建的Binding没有正确关联
Item的实时状态,也未监听Item内部的变化通知。
方案一:将Item改为值类型(推荐)
SwiftUI对值类型的状态变化处理更直接,把Item从class改为struct,移除ObservableObject协议,修改value时会生成新的Item实例,触发数组的@Published更新,视图自动同步状态。
完整修改后代码:
import SwiftUI @main struct DataGridViewApp: App { let tableViewProvider = TableViewProvider() var body: some Scene { WindowGroup { ContentView(viewProvider: tableViewProvider) .onAppear() { tableViewProvider.addElements() } } } } struct ContentView: View { @ObservedObject var viewProvider: TableViewProvider var body: some View { Table($viewProvider.tableViewDataList) { TableColumn("Value") { $item in Toggle("", isOn: $item.value) } TableColumn("ID") { item in Text(String(item.id)) } } } } class TableViewProvider: ObservableObject { @Published var tableViewDataList: [Item] = [] func addElements() { tableViewDataList.append(Item(id: 1)) tableViewDataList.append(Item(id: 2)) tableViewDataList.append(Item(id: 3)) } } struct Item: Identifiable { var id: Int var value: Bool = false init(id: Int) { self.id = id } }
关键改动说明:
Item改为struct,遵循SwiftUI数据管理的最佳实践,值类型的状态变更会自动触发视图更新。- Table使用绑定数组
$viewProvider.tableViewDataList,TableColumn直接获取$item绑定,Toggle直接关联$item.value,代码简洁且状态同步可靠。
方案二:保留Item为引用类型(兼容场景)
若必须保留Item为class,可将Toggle封装为独立子视图,通过@ObservedObject监听单个Item的变化:
修改后的ContentView及新增子视图:
struct ContentView: View { @ObservedObject var viewProvider: TableViewProvider var body: some View { Table(viewProvider.tableViewDataList) { TableColumn("Value") { item in ToggleView(item: item) } TableColumn("ID") { item in Text(String(item.id)) } } } } struct ToggleView: View { @ObservedObject var item: Item var body: some View { Toggle("", isOn: $item.value) } }
关键改动说明:
- 子视图
ToggleView通过@ObservedObject监听Item的@Published属性变化,当value变更时自动刷新Toggle状态。 - 无需手动构建复杂Binding,直接使用
$item.value实现双向绑定,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Frederik Mrozek
相关产品推荐
相关产品推荐

