Isaac
Isaac

Reputation: 715

SwiftUI List how to identify what item is selected on macOS

Here is what I have based on this answer. The code currently allows the user to select a cell but I cannot distinguish which cell is selected or execute any code in response to the selection. In summary, how can I execute code based on the selected cell's name and execute on click. The cell currently highlights in blue where clicked, but I want to identify it and act accordingly based on that selection. Note: I am not looking to select the cell in editing mode. Also, how can I programmatically select a cell without click?

struct OtherView: View {
    @State var list: [String]
    @State var selectKeeper = Set<String>()

    var body: some View {
        NavigationView {
            List(list, id: \.self, selection: $selectKeeper) { item in
                Text(item)
            }
        }
    }
}



Here is a gif demoing the selection

Upvotes: 5

Views: 5961

Answers (3)

Brandon Horst
Brandon Horst

Reputation: 2070

You can react to the selected item by using onChange on your selection variable.

You can set the selection manually by simply setting the variable. This will also trigger onChange.

Here's some example code that will run directly in Playgrounds:

import SwiftUI
import PlaygroundSupport

struct OtherView: View {
    @State var list: [String] = ["a", "b", "c"]
    @State var selection: String?

    var body: some View {
        NavigationView {
            VStack {
                List(list, id: \.self, selection: $selection) { item in
                    Text(item)
                }
                .onChange(of: selection) {s in
                    // React to changes here
                    print(s)
                }
                
                Button("Select b") {
                    // Example of setting selection programmatically
                    selection = "b"
                }
            }
        }
    }
}

let view = OtherView()
PlaygroundPage.current.setLiveView(view)

Upvotes: 1

P. A. Monsaille
P. A. Monsaille

Reputation: 207

To spare you the labour pains:

import SwiftUI

struct ContentView: View {
    @State private var selection: String?
    let list: [String] = ["First", "Second", "Third"]
    
    var body: some View {
        NavigationView {
            HStack {
                List(selection: $selection) {
                    ForEach(list, id: \.self) { item in
                        VStack {
                            Text(item)
                        }
                    }
                }
                TextField("Option", text: Binding(self.$selection) ?? .constant(""))
            }
            .frame(minWidth: 100, maxWidth: .infinity, minHeight: 100, maxHeight: .infinity)
        }
    }
}

This solution deals with the problem @Isaac addressed.

screenshot

Upvotes: 0

Isaac
Isaac

Reputation: 715

I found a workaround, but the text itself has to be clicked- clicking the cell does nothing:

struct OtherView: View {
    @State var list: [String]
    @State var selectKeeper = Set<String>()

    var body: some View {
        NavigationView {
            List(list, id: \.self, selection: $selectKeeper) { item in
                Text(item)
                  .onTapGesture {
                     print(item)
                  }
            }
        }
    }
}

Upvotes: 5

Related Questions