I want to implement a swipe-to-delete functionality on a SwiftUI Section
by using the .onDelete
modifier. The problem is that it always deletes the first item in the list.
My view has a list with dynamic sections created with a ForEach
.
struct SetListView : View {
var setlist: Setlist
var body : some View {
List {
ForEach(setlist.sets) {
SetSection(number: $0.id, songs: $0.songs)
}
}
.listStyle(.grouped)
}
}
In each section, there is another ForEach
to create the dynamic rows:
private struct SetSection : View {
var number: Int
@State var songs: [Song]
var body : some View {
Section (header: Text("Set \(number)"), footer: Spacer()) {
ForEach(songs) { song in
SongRow(song: song)
}
.onDelete { index in
self.songs.remove(at: index.first!)
}
}
}
}
While debugging, I found out that the IndexSet
is referring to the current section instead of the row. So when deleting items from the first section, always the first item gets deleted (as the index for the first section is 0).
Is this a bug in SwiftUI?
If not, then how could I get the index for the row?
It seems to work fine on Xcode 12.5
I'm using it like this:
struct Sections: View {
var items: [SomeData]
private var sections: [Date: [SomeData]] {
Dictionary(grouping: items, by: { $0.date })
}
private var headers: [Date] {
sections.map({ $0.key }).sorted().reversed()
}
var body: some View {
List {
ForEach(headers, id: \.self) { date in
Section(header: Text(date.friendly) {
AList(items: sections[date]!)
}
}
}
}
}
struct AList: View {
var items: [SomeData]
var body: some View {
ForEach(items) { data in
...
}
.onDelete(perform: delete)
}
private func delete(at offsets: IndexSet) {
// You can use `items.remove(atOffsets: offsets)`
for offset in offsets {
let data = items[offset]
print("\(data)")
// You can check here that this is the item that you want to remove and then you need to remove it from your data source.
// I'm using Realm and @Published vars that works fine, you should adapt to your logic.
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With