SwiftUI中如何修改二维列表的元素值?
解决SwiftUI中点击修改二维列表
date值的问题 问题根源
contactGroups被声明为let常量,完全不可修改;ContactGroup结构体里的contacts是let数组,即便外部变量改成可变,也无法修改数组内的元素;- ForEach遍历出的
contact是只读副本,直接赋值contact.date不会影响原数据,还会触发常量赋值报错。
解决步骤与代码修改
1. 调整结构体的可变属性
把ContactGroup中的contacts从let改为var,允许修改组内的联系人列表:
struct ContactGroup: Identifiable { let id = UUID() let name: String var contacts: [Contact] // 修改为var } struct Contact: Identifiable { let id = UUID() let name: String var date: String // 这里原本就是var,无需修改 }
2. 将数据源转为可绑定状态变量
把DashBoardView里的contactGroups从let改为@State var,让SwiftUI能监听数据变化并自动刷新视图:
struct DashBoardView: View { @State var contactGroups: [ContactGroup] = [ ContactGroup( name: "Favourite", contacts: [ Contact(name: "John", date: "01/12"), Contact(name: "Foo", date: "18/06"), Contact(name: "Bar", date: "08/02") ]), ContactGroup( name: "Network Security", contacts: [ Contact(name: "Alice", date: "31/07"), Contact(name: "Bob", date: "31/10"), ]), ] // 后续body部分修改如下 }
3. 使用绑定式ForEach修改数据(推荐)
通过$符号绑定整个分组和联系人,直接修改绑定对象的属性:
var body: some View { List($contactGroups) { $group in Section { ForEach($group.contacts) { $contact in VStack { Text(contact.name) Text(contact.date) }.onTapGesture { contact.date = "31/02" // 直接修改绑定的contact属性 print(contact.date) } } } header: { Text(group.name) } } }
备选方案:通过索引定位修改
如果更习惯用索引操作,也可以通过枚举索引找到对应元素修改:
var body: some View { List(Array(contactGroups.enumerated()), id: \.element.id) { groupIndex, group in Section { ForEach(Array(group.contacts.enumerated()), id: \.element.id) { contactIndex, contact in VStack { Text(contact.name) Text(contact.date) }.onTapGesture { contactGroups[groupIndex].contacts[contactIndex].date = "31/02" print(contactGroups[groupIndex].contacts[contactIndex].date) } } } header: { Text(group.name) } } }
内容的提问来源于stack exchange,提问作者Bassam
相关产品推荐
相关产品推荐

