如何在 Swift 5.5 中使用 List 中的新绑定?
Posted
技术标签:
【中文标题】如何在 Swift 5.5 中使用 List 中的新绑定?【英文标题】:How do I use the new binding in List with Swift 5.5? 【发布时间】:2021-07-30 13:02:48 【问题描述】:我正在尝试 SwiftUI 3(或者更确切地说是 Swift 5.5)中的新功能,您可以在其中直接绑定到列表中的项目。 应该很简单,但是我看不懂。
Xcode 测试版 4。
我可以单击列表中的一个项目,从而激活 TextField。但是,输入一个字符后,TextField 会失去焦点。
简单示例,我尝试在 MAC 和 ios 上运行它,结果相同。
struct ContentView: View
@State private var items = ["Item A", "Item B", "Item C"]
var body: some View
List ($items, id: \.self) $item in
TextField("EditItem", text: $item)
【问题讨论】:
您是在测试新的更新还是想用它解决您的编程问题? 永远不要使用 'id: \.self' 这是一个严重的错误 @malhal 为什么?如果你有一个可散列的唯一值,为什么它是一个“严重错误”? @jnpdx 它会导致内存泄漏,因为在状态更改后再次调用主体时,SwiftUI 无法识别匹配的数据。文档状态 ID 需要是数据的属性,因此它不应该是数据本身。 【参考方案1】:您通过使用\.self
来识别ForEach
中的元素,因此当您直接编辑一个字符串时,它会因为它被更改而获得一个新的身份,然后SwiftUI 将其视为对象的删除并插入新的对象而不是现有对象的更新。
当我尝试使用符合 Identifiable
的结构时,它可以正常工作,因为 SwiftUI 可以使用 id
属性跟踪更改的对象。
struct Item: Identifiable
let id = UUID()
var name: String
struct ContentView: View
@State private var items = [Item(name: "Item A"), Item(name:"Item B"), Item(name: "Item C")]
var body: some View
VStack
List($items, id: \.id) $item in
TextField("EditItem", text: $item.name)
Text(items.map(\.name).joined(separator: " : "))
请注意,这很可能与 SwiftUI 3.0 或任何测试版无关,但更多的是预期行为
【讨论】:
非常感谢,这完全有道理!以上是关于如何在 Swift 5.5 中使用 List 中的新绑定?的主要内容,如果未能解决你的问题,请参考以下文章
Swift 5.5 并发:如何序列化异步任务以用 maxConcurrentOperationCount = 1 替换 OperationQueue?
如何使用 SwiftUI 按按钮移动到另一个视图 - swift 5.5
.task 崩溃 - Swift 5.5 (iOS 15 Beta 5)