如何处理SwiftUI List数组使用.reversed()后.onDelete删除错位问题
问题原因
你遇到的删除错位问题本质是下标不匹配:onDelete回调拿到的下标是对应反转后的数组的位置,你直接传给原始数组执行删除,自然对应到了错误的元素。举个例子:原始数组是[A,B,C,D],反转后展示顺序是D,C,B,A,你删除展示出来的最后一项A(反转数组下标3),直接传3给原始数组就会删掉原始数组下标3的D,也就是展示列表的第一项,和你预期的结果完全相反。
方案1:转换下标适配反转逻辑
不用改现有数组添加逻辑,只需要在onDelete里把反转后的下标转换成原始数组的正确下标即可:
ForEach(viewModel.itemList.reversed()) { item in Text(item.listItem) }.onDelete { indexSet in // 把反转数组的下标转换成原始数组下标 let originalIndices = indexSet.map { viewModel.itemList.count - 1 - $0 } // 按降序删除避免下标偏移出错 viewModel.itemList.remove(atOffsets: IndexSet(originalIndices.sorted(by: >))) }
方案2:直接插入数组头部,完全避免反转
这种是更简单的实现方案,你想要新项展示在顶部,直接把新元素插入原始数组最前面就行,完全不需要给ForEach加reversed,删除逻辑也不用额外处理:
首先修改ViewModel的添加方法:
func addToList( _ item: ToDoModel) { // 替换原来的append,直接插在数组头部 itemList.insert(item, at: 0) }
然后修改ContentView里的ForEach代码,删掉reversed即可:
ForEach(viewModel.itemList) { item in Text(item.listItem) }.onDelete { index in self.viewModel.itemList.remove(atOffsets: index) }
这个方案逻辑更简洁,也不容易出现下标匹配错误,更推荐使用。
内容的提问来源于stack exchange,提问作者JS_is_awesome18
相关产品推荐
相关产品推荐

