SwiftUI:使用onDelete() 删除项目

译自 Deleting items using onDelete()

SwiftUI为我们提供了onDelete()修饰符,可用于控制应该如何从集合中删除对象。实际上,这几乎完全用于ListForEach:我们创建一个使用ForEach显示的行列表,然后将onDelete()附加到该ForEach,以便用户可以删除不需要的行。

这是SwiftUI代替我们做大量工作的另一个地方,但是您确实会发现一些有趣且怪异的东西。

首先,让我们构造一个可以使用的示例:一个显示数字的列表,每当我们点击按钮时,都会出现一个新数字。这是该代码:

struct ContentView: View {
    @State private var numbers = [Int]()
    @State private var currentNumber = 1

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

            Button("Add Number") {
                self.numbers.append(self.currentNumber)
                self.currentNumber += 1
            }
        }
    }
}

现在,您可能会认为不需要ForEach——该列表由完全动态的行组成,因此我们可以这样写:

List(numbers, id: \.self) {
    Text("\($0)")
}

这样做也可以,但是这是我们的第一个奇怪的点:onDelete()修饰符仅存在于ForEach上,因此,如果我们希望用户从列表中删除项目,则必须将这些项目放在ForEach中。当我们只有动态行时,这的确意味着少量的额外代码,但另一方面,这意味着创建仅可以删除某些行的列表会更容易。

为了使onDelete()正常工作,我们需要实现一个方法,该方法将接收类型为IndexSet的单个参数。这有点像一组整数,只不过是经过排序的,它只是告诉我们ForEach中应删除的所有项目的位置。

由于我们的ForEach完全是由单个数组创建的,因此实际上我们可以直接将索引集直接传递给我们的数字数组——它具有一个特殊的remove(atOffsets :)方法来接受索引集。

因此,现在将此方法添加到ContentView中:

func removeRows(at offsets: IndexSet) {
    numbers.remove(atOffsets: offsets)
} 

最后,通过将其修改为以下内容,我们可以告诉SwiftUI在要从ForEach中删除数据时调用该方法:

ForEach(numbers, id: \.self) {
    Text("\($0)")
}
.onDelete(perform: removeRows)

现在继续运行您的应用程序,然后添加一些数字。准备就绪后,从右向左在列表中的任何行上滑动,您会发现出现一个删除按钮。您可以点击它,也可以通过进一步滑动来使用iOS的滑动功能来删除功能。

考虑到这很容易,我认为结果确实很好。但是SwiftUI还有另外一个技巧:我们可以在导航栏中添加“Edit/Done按钮,这使用户可以更轻松地删除几行。

首先,将您的VStack包裹在NavigationView中,然后将此修饰符添加到VStack中:

.navigationBarItems(leading: EditButton())

这几乎就是全部——如果运行该应用程序,您会看到可以添加一些数字,然后点击编辑以开始删除这些行。准备就绪后,点按完成以退出编辑模式。鉴于代码花费很少,还不错!

SwiftUI:Sheet弹窗 Hacking with iOS: SwiftUI Edition SwiftUI:使用UserDefaults存储用户设置

赏我一个赞吧~~~

你可能感兴趣的:(SwiftUI:使用onDelete() 删除项目)