【问题标题】:Modifying struct data in a ForEach in SwiftUI在 SwiftUI 中修改 ForEach 中的结构数据
【发布时间】:2020-12-25 09:35:04
【问题描述】:

我有一个概述数据的结构,然后是一个包含结构数组的类。

struct Example: Codable, Identifiable {
     var id: UUID

     var title: String
     var description: String?

     var tags: [String]
}

class Examples: ObservableObject {
     @Published var examples = [Example]()
}

然后,我有一个用按钮显示数据的 ForEach:

ForEach(examples.examples) { example in
     VStack {
         Button("Complete") {
            example.completed = true
         }
         Text(example.title)
     }
}

当我尝试运行时,它给了我错误“无法分配给属性:'example' is a 'let' constant。”我尝试使用@Binding var(来自this post)将示例传递到单独的视图中,并使用索引(来自this post)修改数据,但两者都给我一个错误,说Xcode无法生成诊断报告并提交反馈。如何修改数据?

对不起,如果这是一个不好的问题,我对 SwiftUI 很陌生

【问题讨论】:

    标签: swift foreach swiftui


    【解决方案1】:

    这是因为 ForEach 会返回原始example 的只读副本 以供您操作,并且您无法对其进行修改。即使你可以,它也不会是同一个结构(结构是值类型)。

    您需要访问原始项目:

    var body: some View {
        ForEach(examples.examples.indices) { index in
            VStack {
                Button("Complete") {
                    examples.examples[index].completed = true
                }
                Text(examples.examples[index].title)
            }
        }
    }
    

    【讨论】:

    • 如果您希望能够在示例数组中重新排序/删除/插入项目,我相信这种方法不起作用。对这种情况有什么想法吗? ForEach 中的项目需要通过 id 属性而不是索引来标识。
    • @Anton 你可以枚举数据 ForEach(Array(examples.enumerated), id: \.element) { index, element in ... }
    【解决方案2】:
    struct Example: Identifiable {
        var id = UUID()
        var title: String
        var description: String
        var tags: [String]
        var completed = false
    }
    
    class Examples: ObservableObject {
        @Published var examples : [Example]
        
        init() {
            self.examples = [Example(title: "Title 1", description: "Desc 1", tags: ["tag 1", "tag 1.1", "tag 1.2"]),
                             Example(title: "Title 2", description: "Desc 2", tags: ["tag 2"]),
                             Example(title: "Title 3", description: "Desc 3", tags: ["tag 3", "tag 3.1"])
            ]
        }
    }
    
    struct ContentView: View {
        @ObservedObject var examples = Examples()
        var body: some View {
            ForEach($examples.examples) { $example in
                VStack {
                    Button("Complete") {
                        example.completed.toggle()
                    }
                    Text(example.title + " " + example.completed.description)
                    TextField("Description", text: $example.description)
                        
                    ForEach($example.tags, id: \.self) { $t in
                        TextField("Tag ", text: $t)
                    }
                }
                .multilineTextAlignment(.center)
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-21
      • 1970-01-01
      • 1970-01-01
      • 2020-05-23
      • 1970-01-01
      • 2023-03-19
      相关资源
      最近更新 更多