I used a SwiftUI EditButton() together with a List(), however it suddenly stopped working with iOS15. I do not use a wrapping NavigationView though, however, it worked nicely before. Using a NavigationView is anyways not an option for me.
struct Test: View {
@State private var items: [String] = ["Item1", "Item2", "Item3"] // mock / demo
var body: some View {
VTile(padding: 0) {
HStack {
Text("Title")
Spacer()
}
.overlay(EditButton())
List {
ForEach(items, id: \.self) { item in
HStack {
Text(item)
Spacer()
}
}
.onDelete(perform: delete)
.onMove(perform: move)
}
.listStyle(PlainListStyle())
}
}
func move(from source: IndexSet, to destination: Int) {
// ...
}
func delete(at offsets: IndexSet) {
// ...
}
}
I also tried using @Environment(\.editMode) var editMode
but that doesn't work either. The List just mever shows the "move" bars on the right, regardless of the environmental edit-mode.
EDIT: What I just noticed is that after a refresh (close & re-open the view containing the list) the list then is in edit mode. Is thhis a bug or is there a clean implementation approach that does work (without using a NavigationView thought).
Workaround: I therefore came up with the following workaround that solved the issue for now but might have side-effects in some situations. Since as observed, refreshing the list brings it into edit mode. Therefore manually forcing a re-rendering when editmode is toggled (e.g. by observing the editMode environmental variable) brings the desired result. To re-render any SwiftUI element simply apply it an unique id. Changing that id later will force the view to re-render.
@Environment(\.editMode) var editMode
@State private var updateId: UUID = UUID()
// ...
List { /* ... */ }.id(updateId)
// ...
func toggleEditMode() {
// toggle edit mode
editMode.toggle()
// force update
updateId = UUID() // <------- update the list
}
VTile(padding: 0)
toVStack(spacing: 10)
. – Maroney