4

SwiftUI List will automatically highlight the tapped row, iff there is a NavigationLink inside.

Since I use SwiftUI embedded in UIKit via UIHostingController, I handle my navigation with a UINavigationController, so I do not want to use NavigationLink.

However, I need the List rows to be highlighted on tap, which is not there when using .onTapGesture

How can I do that?

Here is an example:

List {
    Section(header: Text("Section header text")) {
        HStack { // A row in the list
                Image(systemName: "circle")
                VStack(alignment: .leading) {
                    Text("profile name")
                    // Sub label
                    Text("Description")
                        .foregroundColor(.secondary)
                        .font(.system(size: 12))
            }
            Spacer()
        }
        .contentShape(Rectangle())
        .onTapGesture { // Detect tap on the row
            Print("Perform action here...")
            // THE TAP IS NOT ANIMATED BECAUSE THERE IS NO NAVIGATION LINK HERE.
        }
    }
}
vomi
  • 993
  • 8
  • 18
  • show a minimal example code that you have, and the desired display. See: https://stackoverflow.com/help/minimal-reproducible-example – workingdog support Ukraine Sep 05 '22 at 07:26
  • I added some code to illustrate, thanks – vomi Sep 05 '22 at 07:48
  • Does this answer your question? [SwiftUI List with NavigationLink how to make custom highlight on tap](https://stackoverflow.com/questions/59089400/swiftui-list-with-navigationlink-how-to-make-custom-highlight-on-tap) – Ptit Xav Sep 05 '22 at 07:56
  • Not at all, I want highlight WITHOUT NavigationLink. The EmptyView used there has not helped when I tried. But thanks anyway. – vomi Sep 05 '22 at 08:01

2 Answers2

7

why not use Button()

struct ContentView: View {
var body: some View {
    List {
        Section(header: Text("Section header text")) {
            
            Button(action: {
                print("Perform action here...")
                
            }, label: {
                HStack { // A row in the list
                        Image(systemName: "circle")
                        .foregroundColor(.primary)
                        VStack(alignment: .leading) {
                            Text("profile name")
                                .foregroundColor(.primary)
                            // Sub label
                            Text("Description")
                                .foregroundColor(.secondary)
                                .font(.system(size: 12))
                    }
                    Spacer()
                }
            })
            .contentShape(Rectangle())
            
        }
    }
}
}

enter image description here

AdR
  • 572
  • 1
  • 4
  • 13
0

you could try this approach, using listRowBackground and a selected row/item:

struct ContentView: View {
    @State var selected = ""  // <-- here
    @State var arr = ["item-1", "item-2"]
    
    var body: some View {
        List (arr, id: \.self) { item in
            Section(header: Text("Section header text")) {
                HStack { // A row in the list
                    Image(systemName: "circle")
                    VStack(alignment: .leading) {
                        Text("profile name")
                        Text("Description").foregroundColor(.secondary).font(.system(size: 12))
                    }
                    Spacer()
                }
                .contentShape(Rectangle())
                .onTapGesture {
                    selected = item  // <-- here
                }
                .listRowBackground(selected == item ? Color.red : Color.clear) // <-- here, adjust to your needs
            }
        }
    }
}