John
John

Reputation: 1467

SwiftUI List Selection: Have to Tap Twice to Deselect Item Initially

Why do you have to tap twice to deselect "Item 1"? Am I doing something wrong? If not, is there a workaround? It happens both in the simulator and on my iPhone.

Steps:

  1. Tap "Item 1". Nothing happens. Do not tap another item first. Also, it only happens once so restart the app to retry.
  2. Tap "Item 1" again. It is deselected.
import SwiftUI

struct ContentView: View {
    @State private var selectedItems: Set<Int> = [1]
    
    var body: some View {
        NavigationView { // Some apparent solutions do not work inside a NavigationView
            List(selection: $selectedItems) {
                Text("Item 1").tag(1)
                Text("Item 2").tag(2)
                Text("Item 3").tag(3)
            }.environment(\.editMode, Binding.constant(EditMode.active))
        }
    }
}

Upvotes: 2

Views: 467

Answers (2)

John
John

Reputation: 1467

To prevent the double-click issue, set the selection in onAppear inside the List:

import SwiftUI

struct ContentView: View {
    @State private var selectedItems: Set<Int> = []
    
    var body: some View {
        NavigationView { // Some apparent solutions do not work inside a NavigationView
            List(selection: $selectedItems) {
                Text("Item 1").tag(1)
                Text("Item 2").tag(2)
                Text("Item 3").tag(3).onAppear() { // onAppear inside the List!
                    selectedItems = [1]
                }
            }.environment(\.editMode, Binding.constant(EditMode.active))
        }
    }
}

Note that this sample code sets the same selection on every onAppear. Depending on how your app should behave you will have to change it.

If you have a ForEach in your List, you can attach the onAppear to it.

Upvotes: 0

ChrisR
ChrisR

Reputation: 12155

Not sure why, but it seems to be the access to .environment.
Using a classical @Environment var works for me:

struct ContentView: View {
    
    @State private var selectedItems: Set<Int> = [1]
    @Environment(\.editMode) var editMode
    
    var body: some View {
        
        List(selection: $selectedItems) {
            Text("Item 1").tag(1)
            Text("Item 2").tag(2)
            Text("Item 3").tag(3)
        }
//        .environment(\.editMode, Binding.constant(EditMode.active))
        
        // try this instead
        .onAppear {
            editMode?.wrappedValue = EditMode.active
        }
    }
}

Upvotes: 1

Related Questions