Home > OS >  Force deselection of row in SwiftUI List view
Force deselection of row in SwiftUI List view

Time:11-10

I am using a List with a selection Binding. My expectation is that clearing the selection should update the List to not have any selected rows but the row UI remains selected.

Here is the example code:

struct ContentView: View {
    @State private var selection: String?

    let names = [
        "a",
        "b",
        "c",
        "d"
    ]

    var body: some View {
        NavigationView {
            VStack {
                List(names, id: \.self, selection: $selection) { name in
                    Text(name)
                }

                Button("Deselect") {
                    self.selection = nil
                }
            }
        }
    }
}

I expect that when clearing the selection on button press, the list should update to not have any selection but it remains selected.

Deselection image

CodePudding user response:

Working on iOS 16

import SwiftUI

        struct listSelection: View {
            
            @State private var selection: String?
            
            let names = [
                "a",
                "b",
                "c",
                "d"
            ]
            
            var body: some View {
                NavigationView {
                    VStack {
                        List(names, id: \.self, selection: $selection) { name in
                            Text(name)
                        }
                        .id(UUID())
                        
                        Button("Deselect") {
                            selection = nil
                        }
                    }
                }
            }
        }

enter image description here

CodePudding user response:

You can use listRowBackground modifier to set background based on selection.

struct ContentView: View {
    @State private var selection: String?

    let names = ["Munny", "Badnam", "Hui", "Tereliye"]

    var body: some View {
        NavigationView {
            VStack {
                List(names, id: \.self, selection: $selection) { name in
                    Text(name)
                        .listRowBackground(selection == name ? Color.black.opacity(0.2) : Color.white)
                }

                Button("Deselect") {
                    self.selection = .none
                }
            }
        }
    }
}

Demo

CodePudding user response:

Single row selection is designed for when in edit mode, which you can turn on with the code below and it makes deselection work:

struct ListTestView2: View {
    @State var editMode:EditMode = EditMode.active
    @State private var selection: String?
    
    let names = [
        "a",
        "b",
        "c",
        "d"
    ]
    
    var body: some View {
        NavigationView {
            VStack {
                List(names, id: \.self, selection: $selection) { name in
                    Text(name)
                }
                .environment(\.editMode, $editMode)
                Button("Deselect") {
                    self.selection = nil
                }
            }
        }
    }
}
  • Related