Search code examples
listswiftuidelete-row

How to delete multiple rows from List in SwiftUI?


I took an example from this question: How does one enable selections in SwiftUI's List and edited the code to be able to delete rows one by one. But I don't know how to delete multiple rows from list.

Could you help me, please?

var demoData = ["Phil Swanson", "Karen Gibbons", "Grant Kilman", "Wanda Green"]

struct ContentView : View {
    @State var selectKeeper = Set<String>()

    var body: some View {
        NavigationView {
            List(selection: $selectKeeper){
                ForEach(demoData, id: \.self) { name in
                    Text(name)
                }
                .onDelete(perform: delete)
            }
            .navigationBarItems(trailing: EditButton())
            .navigationBarTitle(Text("Selection Demo \(selectKeeper.count)"))
        }
    }

    func delete(at offsets: IndexSet) {
        demoData.remove(atOffsets: offsets)
    }
}

Solution

  • solution from SwiftUI how to perform action when EditMode changes?

     struct Item: Identifiable {
        let id = UUID()
        let title: String
    
        static var i = 0
        init() {
            self.title = "\(Item.i)"
            Item.i += 1
        }
    }
    
    struct ContentView: View {
        @State var editMode: EditMode = .inactive
        @State var selection = Set<UUID>()
        @State var items = [Item(), Item(), Item()]
    
        var body: some View {
            NavigationView {
                List(selection: $selection) {
                    ForEach(items) { item in
                        Text(item.title)
                    }
                }
                .navigationBarTitle(Text("Demo"))
                .navigationBarItems(
                    leading: editButton,
                    trailing: addDelButton
                )
                .environment(\.editMode, self.$editMode)
            }
        }
    
        private var editButton: some View {
            Button(action: {
                self.editMode.toggle()
                self.selection = Set<UUID>()
            }) {
                Text(self.editMode.title)
            }
        }
    
        private var addDelButton: some View {
            if editMode == .inactive {
                return Button(action: addItem) {
                    Image(systemName: "plus")
                }
            } else {
                return Button(action: deleteItems) {
                    Image(systemName: "trash")
                }
            }
        }
    
        private func addItem() {
            items.append(Item())
        }
    
        private func deleteItems() {
            for id in selection {
                if let index = items.lastIndex(where: { $0.id == id }) {
                    items.remove(at: index)
                }
            }
            selection = Set<UUID>()
        }
    }
    
    extension EditMode {
        var title: String {
            self == .active ? "Done" : "Edit"
        }
    
        mutating func toggle() {
            self = self == .active ? .inactive : .active
        }
    }