带有@Binding控件的SwiftUI动态列表
SwiftUI dynamic List with @Binding controls
如何在不手动引用数组的情况下使用@Binding 驱动的控件构建动态列表?这看起来很明显,但是使用 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")
}
}
}
这行不通:
...
Section {
List($items, id: \.id) { item in
Toggle(item.label, isOn: item.value)
}
}
...
Type '_' has no member 'id'
也没有:
...
Section {
List($items) { item in
Toggle(item.label, isOn: item.value)
}
}
...
Generic parameter 'SelectionValue' could not be inferred
试试
...
Section {
List(items.indices) { index in
Toggle(self.items[index].label, isOn: self.$items[index].value)
}
}
...
虽然 Maki 的回答有效(在某些情况下)。它不是最优的,它是 discouraged by Apple. Instead, they proposed the following solution 在 WWDC 2021 期间:
Simply pass a binding to your collection into the list, using the
normal dollar sign operator, and SwiftUI will pass back a binding to
each individual element within the closure.
像这样:
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")
}
}
}
如何在不手动引用数组的情况下使用@Binding 驱动的控件构建动态列表?这看起来很明显,但是使用 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")
}
}
}
这行不通:
...
Section {
List($items, id: \.id) { item in
Toggle(item.label, isOn: item.value)
}
}
...
Type '_' has no member 'id'
也没有:
...
Section {
List($items) { item in
Toggle(item.label, isOn: item.value)
}
}
...
Generic parameter 'SelectionValue' could not be inferred
试试
...
Section {
List(items.indices) { index in
Toggle(self.items[index].label, isOn: self.$items[index].value)
}
}
...
虽然 Maki 的回答有效(在某些情况下)。它不是最优的,它是 discouraged by Apple. Instead, they proposed the following solution 在 WWDC 2021 期间:
Simply pass a binding to your collection into the list, using the normal dollar sign operator, and SwiftUI will pass back a binding to each individual element within the closure.
像这样:
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")
}
}
}