0

I'm running into some issues with my move and delete methods. This is a follow up to this question: SwiftUI Section from attribute of a struct

I'm trying to group people by company, and the solution provided in the previous question works great. It does have an effect on my move and delete methods and I'm finding it difficult to figure out why.

The delete function appears to be deleting rows that I didn't select, and the move method crashes with Attempt to create two animations for cell.

struct Person: Identifiable {
    var id = UUID()
    var name: String
    var company: String
}

class PeopleList: ObservableObject {

    @Published var people = [
        Person(name: "Bob", company: "Apple"),
        Person(name: "Bill", company: "Microsoft"),
        Person(name: "Brenda", company: "Apple"),
        Person(name: "Lucas", company: "Microsoft"),
    ]

    func getGroups() -> [String] {

        var groups : [String] = []

        for person in people {
            if !groups.contains(person.company) {
                groups.append(person.company)
            }
        }
        return groups
    }

    func deleteListItem(whichElement: IndexSet) {
        people.remove(atOffsets: whichElement)
    }

    func moveListItem(whichElement: IndexSet, destination: Int) {
        people.move(fromOffsets: whichElement, toOffset: destination)
    }
}

struct  ContentView: View {
    @ObservedObject var peopleList = PeopleList()

    var body: some View {
        NavigationView {
            List () {
                ForEach (peopleList.getGroups(), id: \.self) { group in
                    Section(header: Text(group)) {
                        ForEach(self.peopleList.people.filter { $0.company == group }) { person in

                            Text(person.name)
                        }
                        .onDelete(perform: self.peopleList.deleteListItem)
                        .onMove(perform: self.peopleList.moveListItem)
                    }
                }
            }
            .listStyle(GroupedListStyle())
            .navigationBarItems(trailing: EditButton())
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

1 Answer 1

1

UPDATED ANSWER - now with new datamodel and working deletion

try this:

struct Person: Identifiable, Hashable {
    var id = UUID()
    var name: String
}

struct Company : Identifiable, Hashable {

    var id = UUID()
    var name: String
    var employees : [Person]
}

class CompanyList: ObservableObject {

    @Published var companies = [
        Company(name: "Apple", employees: [Person(name:"Bob"), Person(name:"Brenda")]),
        Company(name: "Microsoft", employees: [Person(name:"Bill"), Person(name:"Lucas")])
    ]

    func deleteListItem(whichElement: IndexSet, from company: Company) {

        let index = companies.firstIndex(of: company)!

        companies[index].employees.remove(atOffsets: whichElement)
    }

//    func moveListItem(whichElement: IndexSet, destination: Int) {
//        companies.employees.move(fromOffsets: whichElement, toOffset: destination)
//    }
}

struct  ContentView: View {
    @ObservedObject var companyList = CompanyList()
    @State var text : String = ""

    var body: some View {
        NavigationView {
            VStack {
                List () {
                    ForEach (companyList.companies, id: \.self) { company in
                        Section(header: Text(company.name)) {
                            ForEach(company.employees) { employee in

                                Text(employee.name).id(UUID())
                            }
                            .onDelete { (indexSet) in
                                self.text = ("\(indexSet), \(indexSet.first)")
                                self.companyList.deleteListItem(whichElement: indexSet, from: company)
                            }

                            //    .onMove(perform: self.companyList.moveListItem)
                        }
                    }
                }
                .listStyle(GroupedListStyle())
                .navigationBarItems(trailing: EditButton())
                Text(text)
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Great, that's very clear. It does seem like the move functionality has some issues. Whenever I move someone in one section they also move in the other section. Are you seeing that too?
yes...well...moving makes really no sense, if we sort them ;) and the other problem - i think - is that the filter result is "undefined" - and even worse - moving to other sections -> cannot work, because then you have to change the company name too....
if you really want to reorder you have to change your data model - i think.
Thanks for all your help Chris. I'll have a think about my data model but I think I can get away with not reordering. I just looked again and am running into an issue where Brenda is deleted when Lucas is selected to be deleted. I've not changed anything in your previous code, so I'm wondering if you're seeing that too? Both Bill and Lucas when they're deleted don't get removed, instead the corresponding ones from the Apple section get removed.
no, i did not have that issue...can you probably make a movie of it and show?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.