Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to delete an item in a swiftui list that consists of dynamic sections?

Tags:

swift

swiftui

Let's say I have a swiftui view show a list of employees sectioned by department, how can I delete an item within a section? The same way swipe left to delete behavior in uitableview.

import SwiftUI

struct ContentView: View {
    var data: [String : [String]] = ["DeptA": ["EmpA", "EmpB", "EmpC"], "DeptB": ["EmpD", "EmpE", "EmpF"]]

    var body: some View {
        NavigationView {

            List {
                ForEach(data.keys.map { String($0) }, id: \.self) { dept in
                    Section(header: Text(dept)) {
                        ForEach(self.data[dept]!, id: \.self) { emp in
                            Text(emp)
                        }.onDelete(perform: self.deleteEmp)
                    }
                }
            }
            .navigationBarTitle("Employees")
        }
    }

    private func deleteEmp(indexSet: IndexSet) {
        print(indexSet.first!)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
like image 566
M.Serag Avatar asked Mar 03 '23 11:03

M.Serag


1 Answers

Remove it from the dataSource:

struct ContentView: View {
    @State var dataSource = ["1", "2", "3", "4"]

    var body: some View {

        List(dataSource, id: \.self) { number in

            Text("Click Here to delete this row " + number)
                .onTapGesture {
                    let index = self.dataSource.firstIndex(of: number)!
                    self.dataSource.remove(at: index)
            }
        }
    }
}

Update duo to your code

You nested your datasource in two ForEachs. First one has access to section and second one has access to row. So:

struct ContentView: View {
    var data: [String : [String]] = ["DeptA": ["EmpA", "EmpB", "EmpC"],
                                     "DeptB": ["EmpD", "EmpE", "EmpF"]]
    var sections: [String] { data.keys.map { $0 } }
    func rows(section: Int) -> [String] { data[sections[section]]! }

    var body: some View {
        NavigationView {

            List {
                ForEach(0..<sections.count, id: \.self) { section in
                    Section(header: Text(self.sections[section])) {
                        ForEach(self.rows(section: section), id: \.self) { emp in
                            Text(emp)
                        }.onDelete { row in
                            self.deleteEmp(section: section, row: row)
                        }
                    }
                }
            }.navigationBarTitle("Employees")
        }
    }

    private func deleteEmp(section: Int, row: IndexSet) {
        print("Section:", section)
        print("Row:", row.first!)
    }
}

Note that I used some helper variable and functions.

like image 141
Mojtaba Hosseini Avatar answered May 14 '23 11:05

Mojtaba Hosseini