因此我了解以下代码可以工作:
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
}
}
}
}
我不了解removeRows(at offsets: IndexSet)
的{{1}}自定义函数处理程序是如何工作的。具体来说,为什么在.onDelete()
之前有一个参数标签at
。例如,您可以使用offsets:
而不是on
吗?参数标签是否只是为了我们更好地理解代码?
然后有一个at
,我认为我可以理解为一种类型,该类型持有一个用于索引目的的Int或用于删除列表中某行的Int范围,以便swiftui知道要删除哪一行?>
我想我了解IndexSet
实际上是用来删除numbers.remove(atOffsets: offsets)
上的列表行的(根据实际的行索引被删除)-但我不确定{{ 1}}实际上是迅速知道的吗?到底是什么offsets
,它的值如何设置?
我正在尝试通过遵循this来学习。我仍然对swiftui有非常基础的知识,所以请像我这样超级菜鸟来解释一下。
答案 0 :(得分:1)
如果您查看onDelete
签名:
@inlinable public func onDelete(perform action: ((IndexSet) -> Void)?) -> some DynamicViewContent
您会看到它需要一个((IndexSet) -> Void)?
类型的参数。
这意味着它需要一个接受IndexSet
参数并返回Void
的函数。
您的removeRows
函数具有与所需类型完全相同的类型:
func removeRows(at offsets: IndexSet) { ...
*以上签名等同于:
func removeRows(at offsets: IndexSet) -> Void { ...
为清楚起见,使用标签at
。也可以称为someCustomLabel
:
func removeRows(someCustomLabel offsets: IndexSet) { ...
但是您需要这样称呼:
removeRows(someCustomLabel: indexSet)
您也可以完全跳过标签:
func removeRows(offsets: IndexSet) { ...
并像这样调用您的函数:
removeRows(offsets: indexSet)
请注意:
.onDelete(perform: removeRows)
与以下相同:
.onDelete(perform: { indexSet in
self.removeRows(at: indexSet)
})
IndexSet
指定要删除的索引。当您在List
中的行上向左滑动时,它会调用onDelete
函数,并在IndexSet
参数中传递行索引。
请注意,numbers.remove(atOffsets: offsets)
期望IndexSet
标签使用atOffsets
参数(并且您不能更改此标签),但是您可以根据需要随意命名参数:>
func removeRows(at indexSetToDelete: IndexSet) {
numbers.remove(atOffsets: indexSetToDelete)
}