带有@Binding 控件的 SwiftUI 动态列表

jos*_*shd 6 swiftui combine swiftui-list

如何使用@Binding-driven 控件构建动态列表而无需手动引用数组?看起来很明显,但是使用 List 或 ForEach 遍历数组会产生各种奇怪的错误。

struct OrderItem : Identifiable {
    let id = UUID()
    var label : String
    var value : Bool = false
}

struct ContentView: View {
    @State var items = [OrderItem(label: "Shirts"),
                        OrderItem(label: "Pants"),
                        OrderItem(label: "Socks")]
    var body: some View {
        NavigationView {
            Form {
                Section {
                    List {
                        Toggle(items[0].label, isOn: $items[0].value)
                        Toggle(items[1].label, isOn: $items[1].value)
                        Toggle(items[2].label, isOn: $items[2].value)
                    }
                }
            }.navigationBarTitle("Clothing")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这不起作用:

            ...
                Section {
                    List($items, id: \.id) { item in
                        Toggle(item.label, isOn: item.value)
                    }
                }
            ...
Run Code Online (Sandbox Code Playgroud)

类型“_”没有成员“id”

也不:

            ...
                Section {
                    List($items) { item in
                        Toggle(item.label, isOn: item.value)
                    }
                }
            ...
Run Code Online (Sandbox Code Playgroud)

无法推断通用参数“SelectionValue”

Mak*_*aki 12

尝试类似的东西

...
   Section {
       List(items.indices) { index in
           Toggle(self.items[index].label, isOn: self.$items[index].value)
       }
   }
...
Run Code Online (Sandbox Code Playgroud)

  • 当数组中的项目数量稍后减少时,这种方法似乎会失效。请参阅/sf/ask/4034185781/ (3认同)
  • 我简直不敢相信!它确实有效。为什么这会起作用而传递对象却不起作用?!! (2认同)

Dam*_*aux 9

虽然 Maki 的答案有效(在某些情况下)。这不是最佳选择,Apple 不鼓励这样做。相反,他们在 WWDC 2021 期间提出了以下解决方案:

只需使用普通的美元符号运算符将集合的绑定传递到列表中,SwiftUI 就会将绑定传回闭包中的每个单独元素。

像这样:

struct ContentView: View {
    @State var items = [OrderItem(label: "Shirts"),
                        OrderItem(label: "Pants"),
                        OrderItem(label: "Socks")]

    var body: some View {
        NavigationView {
            Form {
                Section {
                    List($items) { $item in
                        Toggle(item.label, isOn: $item.value)
                    }
                }
            }.navigationBarTitle("Clothing")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)