7

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
}
Leo
  • 1,508
  • 13
  • 27
  • What I just noticed, the edit-mode automatically toggles back to inactive when: 1. swiping left on one of the list items such that the red delete button appears (but without deleting it), then 2. tap somewhere to make the delete button disapper again – Leo Oct 23 '21 at 09:46
  • 1
    your code seems to work for me, using macos 12.01 with xcode 13.1(RC), targets ios 15 and macCatalyst. Tried on mac 12.01 and iPhone ios15. Although I changed `VTile(padding: 0)` to `VStack(spacing: 10)`. – workingdog support Ukraine Oct 23 '21 at 10:59
  • 1
    interesting, I'm on xcode 13.0, I'll update now and see if that changes anything. I also got it working now by forcing th elist to refresh (assigning an id and changing the id whenever editMode changes) but it's a dirty workaround. – Leo Oct 23 '21 at 11:41
  • 1
    I'm using NavigationView, but my app has same problem. – omusubi Oct 28 '21 at 13:05

0 Answers0