editMode change not recognized in a TabView

Viewed 159

This code works perfectly when not in a TabView. Once it is placed in a TabView, the .editMode change does not appear to have any effect on the List.

struct ContentView: View {
    @Environment(\.editMode) var editMode
    var body: some View {
        TabView {
            myView().tabItem {
             Text("test")
            }.tag(0)
        }
    }
}
struct myView : View {
    @State var list = ["a", "b", "c"]
    @Environment(\.editMode) var editMode

    var body: some View {
        VStack {
            Button(action: {
                if self.editMode?.wrappedValue == .active {
                    self.editMode?.wrappedValue = .inactive
                } else {
                    self.editMode?.wrappedValue = .active
                }
            }, label: {
                Text("Edit")
            })
            List {
                ForEach(list, id:\.self) {val in
                    Text(val)
                }.onDelete(perform: { indexSet in
                    ()
                })
            }
        }
    }
}

Not sure if this is a bug, or if the .editMode is somehow different when in a TabView.

3 Answers

You can explicitly inject the editMode:

struct myView: View {
    @State var list = ["a", "b", "c"]
    @Environment(\.editMode) var editMode

    var body: some View {
        VStack {
            Button(action: {
                if self.editMode?.wrappedValue == .active {
                    self.editMode?.wrappedValue = .inactive
                } else {
                    self.editMode?.wrappedValue = .active
                }
            }, label: {
                Text("Edit")
            })
            List {
                ForEach(list, id: \.self) { val in
                    Text(val)
                }.onDelete(perform: { indexSet in
                    ()
                })
            }
            .environment(\.editMode, editMode) // <- inject here
        }
    }
}

you can toggle editing mode for your list view by adding an EditButton

struct ContentView: View {
   @State var list = ["a", "b", "c"]

   var body: some View {
      NavigationView {
          List {
              ForEach(list, id: \.self) { value in
                  Text(value)
              }
              .onDelete(perform: delete)
          }
          .navigationBarItems(trailing: EditButton())
      }
  }

  func delete(at offsets: IndexSet) {
     list.remove(atOffsets: offsets)
  }
}

Try to use EditButton() instead of creating a normal Button

This worked for me :

VStack {
  EditButton()
  List {
   ForEach(list, id:\.self) {val in
     Text(val)
   }.onDelete(perform: { indexSet in
     ()
   })
  }
 }
Related