Victor Kushnerov
Victor Kushnerov

Reputation: 3964

How to manually remove an item from List in SwiftUI?

I try to remove some item from List but get an error Thread 1: Fatal error: Index out of range. I know about onDelete but on macOS it's not clear how to call it with mouse

    @State var wishList = [
        "Item 1",
        "Item 2"
    ]

List {
    ForEach(wishList.indices) { index in
        Button(action: {

        }) {
            HStack {
                Text(self.wishList[index]) //Thread 1: Fatal error: Index out of range. 
                Button(action: {
                    RunLoop.main.perform {
                        self.wishList.remove(at: index)
                    }
                }) {
                    Image(systemName: "minus.circle").foregroundColor(.red)
                }

            }
        }
    }
}

Fix: I added id:\.self to fix my code.

    @State var wishList = [
        "Item 1",
        "Item 2"
    ]

List {
    ForEach(wishList.indices, id:\.self) { index in
        Button(action: {

        }) {
            HStack {
                Text(self.wishList[index]) //Thread 1: Fatal error: Index out of range. 
                Button(action: {
                    RunLoop.main.perform {
                        self.wishList.remove(at: index)
                    }
                }) {
                    Image(systemName: "minus.circle").foregroundColor(.red)
                }

            }
        }
    }
}

Upvotes: 0

Views: 1520

Answers (1)

Procrastin8
Procrastin8

Reputation: 4503

The cause is given to you in an error:

count (1) != its initial count (2). ForEach(_:content:) should only be used for constant data. Instead conform data to Identifiable or use ForEach(_:id:content:) and provide an explicit id!

Instead, use an Identifiable version and operate directly on the content:

    List {
        ForEach(wishList, id: \.self) { content in
            HStack {
                Text(verbatim: content)

                Button(action: {
                    guard let index = self.wishList.firstIndex(of: content) else { return }
                    self.wishList.remove(at: index)
                }) {
                    Image(systemName: "minus.circle").foregroundColor(.red)
                }
            }
        }
    }

EDIT: Here's a simpler version:

    List(0..<wishList.count, id: \.self) { index in
        HStack {
            Text(verbatim: self.wishList[index])

            Button(action: {
                self.wishList.remove(at: index)
            }) {
                Image(systemName: "minus.circle").foregroundColor(.red)
            }
        }
    }

Upvotes: 2

Related Questions