1

In the following SwiftUI view, why does the conditional .contextMenu not work correctly?

Steps:

  1. Long press the list item
  2. Tap Edit
  3. Long press the list item again

On the second long press the context menu should not appear because editMode?.wrappedValue is .active. But it does appear. How to fix that?

struct ContentView: View {
    @Environment(\.editMode) private var editMode
    
    var body: some View {
        let contextMenu = ContextMenu {
            Button("Do nothing", action: {})
        }
        VStack(alignment: .leading, spacing: 12) {
            EditButton().padding()
            List {
                ForEach(1..<2) {i in
                    Text("Long press me. Editing: \((editMode?.wrappedValue == .active).description)")
                        .contextMenu(editMode?.wrappedValue == .active ? nil : contextMenu)
                }
                    .onDelete(perform: { _ in })
                    .onMove(perform: { _, _ in })
            }
            Spacer()
        }
    }
}
John
  • 964
  • 8
  • 21

1 Answers1

1

Works fine with Xcode 14 / iOS 16

Here is possible workaround for older versions (it is possible to try different places for .id modifier to have appropriate, acceptable, UI feedback)

Tested with Xcode 13.4 / iOS 15.5

Text("Long press me. Editing: \((editMode?.wrappedValue == .active).description)")
    .contextMenu(editMode?.wrappedValue == .active ? nil : contextMenu)
    .id(editMode?.wrappedValue)    // << this !!
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • If I apply any transition, views disappear and appear in this method. Maybe this is because of the id() modifier. – ST K Oct 11 '22 at 14:54