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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 13:05:21