带有 @Binding 控件的 SwiftUI 动态列表
Posted
技术标签:
【中文标题】带有 @Binding 控件的 SwiftUI 动态列表【英文标题】:SwiftUI dynamic List with @Binding controls 【发布时间】:2019-09-07 19:48:36 【问题描述】:如何使用@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)
...
类型“_”没有成员“id”
也没有:
...
Section
List($items) item in
Toggle(item.label, isOn: item.value)
...
无法推断通用参数“SelectionValue”
【问题讨论】:
解决这个问题可以实现更大的目标:要创建一个可以接受 $items 和管理的 ToggleList 视图,请显示切换。 【参考方案1】:试试类似的东西
...
Section
List(items.indices) index in
Toggle(self.items[index].label, isOn: self.$items[index].value)
...
【讨论】:
哇。不敢相信我错过了。我希望我能够传递一个实际的对象,但这会让我到达我需要去的地方。谢谢! 我不敢相信!!它确实有效。为什么这会起作用而传递对象却不起作用??!! 当数组中的项目数量稍后减少时,这种方法似乎会中断。见***.com/questions/57631225/…【参考方案2】:虽然 Maki 的回答有效(在某些情况下)。它不是最佳的,它是discouraged by Apple。相反,他们在 WWDC 2021 期间提出了the following solution:
只需将绑定到您的集合传递到列表中,使用 普通的美元符号运算符,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")
【讨论】:
有趣。这是否仅限于新的 API? 根据 Matt Ricketson 的说法:“您甚至可以将此代码反向部署到 SwiftUI 支持的任何先前版本”。事实上,我认为它使用了 SE-0293 的一个特性(在 Swift 5.5 中实现)。但仅在旧的(v12)Xcode 中安装 5.5 工具链是不够的。我认为您还需要将 init(projectedValue:) 添加到 Binding 并使其符合 RandomAccessCollection 以便将此调整与旧版本的 SwiftUI 一起使用。以上是关于带有 @Binding 控件的 SwiftUI 动态列表的主要内容,如果未能解决你的问题,请参考以下文章
当从 GeometryReader 中进行更改时,SwiftUI 不会反映对 @Binding @State 变量的更改
SwiftUI如何在View在初始化程序中需要@Binding时实例化PreviewProvider
Core Data + SwiftUI:无法将“Bool”类型的值转换为预期的参数类型“Binding<Bool>”
SWIFTUI List 希望在列表中有切换。无法将“MyModel”类型的值转换为预期的参数类型“Binding<MyModel>”