I have created a quiet simple list in SwiftUI and want to make it editable, like a tableView in UIKit. I want to remove a row in the list with the all known gesture (swipe from, the right to the left).
I have tried to make with a button above the list, but it doesn't look nice an is not practicable for my app.
struct singleIsland: Identifiable {
let id: Int
let name:String
}
var islands = [
singleIsland(id: 0, name: "Wangerooge"),
singleIsland(id: 1, name: "Spiekeroog"),
singleIsland(id: 2, name: "Langeoog")
]
var body: some View {
VStack {
List(islands) { island in
Text(island.name)
}
}
}
struct SingleIsland {
let name: String
}
struct ContentView: View {
@State var islands = [
SingleIsland(name: "Wangerooge"),
SingleIsland(name: "Spiekeroog"),
SingleIsland(name: "Langeoog")
]
var body: some View {
List {
ForEach(islands.identified(by: \.name)) { island in
Text(island.name)
}.onDelete(perform: delete)
}
}
private func delete(with indexSet: IndexSet) {
indexSet.forEach { islands.remove(at: $0) }
}
}
Wrapping the data in a @State
makes sure the view is redrawn if it changes.
Note:
I'm getting compilers errors if the List
is built this way:
List(data) { item in
[...]
}
It will complain that onDelete
does not exist for the List
.
My workaround is to use a ForEach
inside the List
, and the onDelete
function on it.
Yes, this is very straight forward with SwiftUI.
Updating your code like this...
struct SingleIsland: Identifiable {
let id: Int
let name:String
}
struct IslandListView: View {
@State private var islands = [
SingleIsland(id: 0, name: "Wangerooge"),
SingleIsland(id: 1, name: "Spiekeroog"),
SingleIsland(id: 2, name: "Langeoog")
]
var body: some View {
List {
ForEach(islands.identified(by: \.name)) { island in
Text(island.name)
}.onDelete(perform: delete)
}
}
func delete(at offsets: IndexSet) {
islands.remove(at: offsets)
}
}
This will allow your view to swipe to delete rows.
Using @State
sets up your view to depend on the islands
array. Any update to that array will trigger the view to reload. So by deleting an item from the array it will animate the change to the list.
Add this to the list:
.onDelete { $0.forEach { islands.remove(at: $0) } }
After you turning islands
into an @State
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