从列表中删除项目时索引不更新
Posted
技术标签:
【中文标题】从列表中删除项目时索引不更新【英文标题】:Indices don't update when deleting item from list 【发布时间】:2021-04-22 03:58:39 【问题描述】:我想创建一个视图,我可以将数组传递到该视图中并让视图编辑数组。下面的代码是一个简化的例子:
struct Item: Identifiable
var name: String
var id = UUID()
struct EditItems: View
@Binding var item_list: [Item]
var body: some View
List
ForEach(item_list.indices) idx in
Text(item_list[idx].name)
.onDelete(perform: deleteItem)
.toolbar
ToolbarItem(placement: .principal)
EditButton()
func deleteItem(at offsets: IndexSet)
item_list.remove(atOffsets: offsets)
这首先编译并运行。我可以点击“编辑”并删除列表项。删除列表项后,当我点击“完成”时,我得到“致命错误:索引超出范围”。调试器告诉我,我的列表有 7 个项目,但 Text(item_list[idx].name)
行正在尝试使用 idx = 7
执行。
因此,在删除项目后,ForEach
似乎仍在旧索引上运行,而不是新的较短索引。这是因为item_list
不是@State
?当我尝试同时使用@State
和@Binding
时,我遇到了一堆错误。
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:ForEach
的初始化器接受一个范围,只能用于常量数据。
来自Apple's docs:
实例只读取提供的数据的初始值并且 不需要跨更新识别视图。
使用其他 ForEach
初始化器之一,例如:
ForEach(item_list.enumerated(), id: \.self) idx, element in
【讨论】:
好吧,我会的,我从来没有注意到其中一些是恒定的,而另一些则不是。谢谢!【参考方案2】:您使用了 ForEach
的构造函数,它创建 constant 容器,使用不同的容器,带有显式标识符,例如
List
ForEach(item_list.indices, id: \.self) idx in // << here !!
Text(item_list[idx].name)
【讨论】:
以上是关于从列表中删除项目时索引不更新的主要内容,如果未能解决你的问题,请参考以下文章