onDelete() 函数处理程序如何在 swiftUI 列表中工作?

Sup*_*oob 6 swift swiftui

所以我知道以下代码有效:

struct ContentView: View {
    func removeRows(at offsets: IndexSet) {
        numbers.remove(atOffsets: offsets)
    }
    
    @State private var numbers = [Int]()
    @State private var currentNumber = 1

    var body: some View {
        VStack {
            List {
                ForEach(numbers, id: \.self) {
                    Text("\($0)")
                }
                .onDelete(perform: removeRows)
            }

            Button("Add Number") {
                self.numbers.append(self.currentNumber)
                self.currentNumber += 1
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白的是removeRows(at offsets: IndexSet)自定义函数处理程序是如何.onDelete()工作的。at具体来说,为什么前面有一个参数标签offsets:。您可以使用on代替at例如吗?参数标签只是为了让我们更好地理解代码吗?

然后,IndexSet我认为我将其理解为一种类型,它保存用于索引目的的 Int 或用于删除列表中的行的 Int 范围,以便 swiftui 知道要删除哪一行?

我想我理解numbers.remove(atOffsets: offsets)用于实际删除列表行offsets(就被删除的实际行索引而言) - 但我不确定offsetsswift 实际上是如何知道的?到底是什么offsets以及它的值是如何设置的?

我正在尝试按照进行学习。我对 swiftui 仍然有非常基本的了解,所以请像我超级菜鸟一样解释一下。

paw*_*222 8

如果你看一下onDelete签名:

@inlinable public func onDelete(perform action: ((IndexSet) -> Void)?) -> some DynamicViewContent
Run Code Online (Sandbox Code Playgroud)

您可以看到它需要一个类型为 的参数((IndexSet) -> Void)?

这意味着它需要一个接受IndexSet参数并返回的函数Void

您的removeRows函数具有与所需完全相同的类型:

func removeRows(at offsets: IndexSet) { ...
Run Code Online (Sandbox Code Playgroud)

*以上签名相当于:

func removeRows(at offsets: IndexSet) -> Void { ...
Run Code Online (Sandbox Code Playgroud)

at使用标签是为了清楚起见。someCustomLabel它也可以被称为:

func removeRows(someCustomLabel offsets: IndexSet) { ...
Run Code Online (Sandbox Code Playgroud)

但你需要这样称呼它:

removeRows(someCustomLabel: indexSet)
Run Code Online (Sandbox Code Playgroud)

您也可以完全跳过标签:

func removeRows(offsets: IndexSet) { ...
Run Code Online (Sandbox Code Playgroud)

并像这样调用你的函数:

removeRows(offsets: indexSet)
Run Code Online (Sandbox Code Playgroud)

注意:

.onDelete(perform: removeRows)
Run Code Online (Sandbox Code Playgroud)

是相同的:

.onDelete(perform: { indexSet in
    self.removeRows(at: indexSet)
})
Run Code Online (Sandbox Code Playgroud)

指定IndexSet要删除的索引。当您在行中向左滑动时,List它会调用在参数onDelete中传递行索引的函数IndexSet

请注意,numbers.remove(atOffsets: offsets)需要标签IndexSet参数atOffsets(并且您无法更改此标签),但您可以根据需要随意命名参数:

func removeRows(at indexSetToDelete: IndexSet) {
    numbers.remove(atOffsets: indexSetToDelete)
}
Run Code Online (Sandbox Code Playgroud)