从 SwiftUI 中的列表中删除绑定
Posted
技术标签:
【中文标题】从 SwiftUI 中的列表中删除绑定【英文标题】:Delete a Binding from a list in SwiftUI 【发布时间】:2021-10-28 02:13:49 【问题描述】:我试图从 Swift 和 SwiftUI 的列表中简单地删除一个元素。如果没有在ForEach
循环中绑定某些东西,它确实会被删除。但是,在绑定某些东西时,它会因错误Index out of range
而崩溃。 ForEach
循环似乎是恒定的,不更新,并试图在特定索引处呈现。
示例查看代码:
@ObservedObject var todoViewModel: TodoViewModel
//...
ForEach(self.todoViewModel.todos.indices) index in
TextField("Test", text: self.$todoViewModel.todos[index].title)
.contextMenu(ContextMenu(menuItems:
VStack
Button(action:
self.todoViewModel.deleteAt(index)
, label:
Label("Delete", systemImage: "trash")
)
))
示例视图模型代码:
final class TodoViewModel: ObservableObject
@Published var todos: [Todo] = []
func deleteAt(_ index: Int) -> Void
self.todos.remove(at: index)
示例型号代码:
struct Todo: Identifiable
var id: Int
var title: String = ""
有谁知道如何从ForEach
循环中绑定的列表中正确删除一个元素?
【问题讨论】:
这是否回答了您的问题***.com/a/58911168/12299030? 遗憾的是没有。我也注意到了这一点,但是您可以在代码中看到我没有使用ForEach
中的任何范围
【参考方案1】:
发生这种情况是因为您通过indices
进行枚举并通过ForEach
内部的索引引用绑定
我建议你切换到ForEachIndexed
:这个包装器会将索引和正确的绑定传递给你的块:
struct ForEachIndexed<Data: MutableCollection&RandomAccessCollection, RowContent: View, ID: Hashable>: View, DynamicViewContent where Data.Index : Hashable
var data: [(Data.Index, Data.Element)]
forEach.data
let forEach: ForEach<[(Data.Index, Data.Element)], ID, RowContent>
init(_ data: Binding<Data>,
@ViewBuilder rowContent: @escaping (Data.Index, Binding<Data.Element>) -> RowContent
) where Data.Element: Identifiable, Data.Element.ID == ID
forEach = ForEach(
Array(zip(data.wrappedValue.indices, data.wrappedValue)),
id: \.1.id
) i, _ in
rowContent(i, Binding(get: data.wrappedValue[i] , set: data.wrappedValue[i] = $0 ))
init(_ data: Binding<Data>,
id: KeyPath<Data.Element, ID>,
@ViewBuilder rowContent: @escaping (Data.Index, Binding<Data.Element>) -> RowContent
)
forEach = ForEach(
Array(zip(data.wrappedValue.indices, data.wrappedValue)),
id: (\.1 as KeyPath<(Data.Index, Data.Element), Data.Element>).appending(path: id)
) i, _ in
rowContent(i, Binding(get: data.wrappedValue[i] , set: data.wrappedValue[i] = $0 ))
var body: some View
forEach
用法:
ForEachIndexed($todoViewModel.todos) index, todoBinding in
TextField("Test", text: todoBinding.title)
.contextMenu(ContextMenu(menuItems:
VStack
Button(action:
self.todoViewModel.deleteAt(index)
, label:
Label("Delete", systemImage: "trash")
)
))
【讨论】:
效果非常好!感谢您的出色工作!以上是关于从 SwiftUI 中的列表中删除绑定的主要内容,如果未能解决你的问题,请参考以下文章