如何使用 .reversed() 处理 SwiftUI 列表数组的 .onDelete
Posted
技术标签:
【中文标题】如何使用 .reversed() 处理 SwiftUI 列表数组的 .onDelete【英文标题】:How to handle .onDelete for SwiftUI list array with .reversed() 【发布时间】:2021-12-31 16:18:46 【问题描述】:我正在尝试制作一个基本的 SwiftUI 列表,其中每个新列表项都显示在列表的顶部。为此,我将 .reversed() 附加到传递到 ForEach 循环的数组中,由viewModel.itemList
表示。我还设置了 .onDelete 来处理列表项的删除。但是,当我删除一个项目时,例如列表中的最后一个项目,它会删除数组中的最后一个项目(列表顶部的项目)。数组反转时如何配置.onDelete删除正确的项?
请参阅下面的代码。谢谢!
内容视图
struct ContentView: View
@StateObject var viewModel = ToDoListViewModel()
@State private var listItemName = ""
var body: some View
NavigationView
VStack(alignment: .leading)
List
ForEach(viewModel.itemList.reversed()) item in
Text(item.listItem)
.onDelete index in
self.viewModel.itemList.remove(atOffsets: index)
HStack
TextField("Enter List Item", text: $listItemName)
Button(action:
viewModel.addToList(ToDoModel(listItem: listItemName))
listItemName = ""
)
Image(systemName: "plus")
.font(.largeTitle)
.frame(width: 75, height: 75)
.foregroundColor(Color.white)
.background(Color.blue)
.clipShape(Circle())
.frame(minWidth: 100, idealWidth: 150, maxWidth: 500, minHeight: 30, idealHeight: 40, maxHeight: 50, alignment: .leading)
.padding(.leading, 16)
.padding(.trailing, 16)
.navigationBarTitle("To Do List", displayMode: .inline)
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
型号
struct ToDoModel: Identifiable, Codable
var id = UUID()
var listItem: String = ""
视图模型
class ToDoListViewModel: ObservableObject
@Published var itemList = [ToDoModel]()
func addToList( _ item: ToDoModel)
itemList.append(item)
【问题讨论】:
【参考方案1】:警告:这可能不是最算法效率最高的方法。但是,对于 List
上的简单删除,它应该可以正常执行。
.onDelete offsets in
let reversed = Array(viewModel.itemList.reversed()) //get the reversed array -- use Array() so we don't get a ReversedCollection
let items = Set(offsets.map reversed[$0].id ) //get the IDs to delete
viewModel.itemList.removeAll items.contains($0.id) //remove the items with IDs that match the Set
【讨论】:
【参考方案2】:你也可以试试这个方法:
.onDelete index in
// get the item from the reversed list
let theItem = viewModel.itemList.reversed()[index.first!]
// get the index of the item from the viewModel, and remove it
if let ndx = viewModel.itemList.firstIndex(of: theItem)
viewModel.itemList.remove(at: ndx)
【讨论】:
以上是关于如何使用 .reversed() 处理 SwiftUI 列表数组的 .onDelete的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 .reversed() 处理 SwiftUI 列表数组的 .onDelete