8
votes

I am using xCode 11 beta 7 with SwiftUI.

I have a simple list which each list element has several buttons. Currently when the user presses the cell(not the buttons) it is highlighting the back of the list cell(probably not the correct terminology for SwiftUI).

How do i disable this behaviour? I could not locate an obvious api to disable it.

List {
    HStack {
        Group {
            Button(action: {}) {
                Text("Read").padding(5)
            }.onTapGesture {
                print("1")                    
            }
            .padding()
            .background(Color.blue)
            .cornerRadius(5)
        }
        Group {
            Button(action: {}) {
                Text("Notify").padding(5)
            }.onTapGesture {
                print("2") 
            }
            .padding()
            .background(Color.purple)
            .cornerRadius(5)
        }
        Group {
            Button(action: {}) {
                Text("Write").padding(5)
            }.onTapGesture {
                print("3")
            }
            .padding()
            .background(Color.yellow)
            .cornerRadius(5)
        }
    }
}
3
You can't disable the highlight of cell directly (yet). But you can use a vertical scrollView instead of list instead. Also you can set a background to block user from seeing the highlighted background, but yet separators will flash - Mojtaba Hosseini
Yes i feel like this might be the solution for now, SwiftUI certainly is not production ready yet. - Reedy
Do you need a hand for that? - Mojtaba Hosseini
ive got two thanks - Reedy
Point of note: List(...) handles large lists far, far better and is far more performant than ScrollView(...), so if that's a thing, find a way to handle the List item tap and forego the scroller. - ChrisH

3 Answers

25
votes

Same answer as in How to remove highlight on tap of List with SwiftUI?

I know I'm a bit late, but it's for those of you who are searching (like me 😇)

What I found

I guess you should take a look at the short article How to disable the overlay color for images inside Button and NavigationLink from @TwoStraws

Just add the .buttonStyle(PlainButtonStyle()) modifier to your item in the List and you'll have what you wanted. It also makes the Buttons work again in the List, which is another problem I encountered.

A working example for Swift 5.1 :

import Combine
import SwiftUI

struct YourItem: Identifiable {
    let id = UUID()
    let text: String
}

class YourDataSource: ObservableObject {
    let willChange = PassthroughSubject<Void, Never>()
    var items = [YourItem]()

    init() {
        items = [
            YourItem(text: "Some text"),
            YourItem(text: "Some other text")
        ]
    }
}

struct YourItemView: View {
    var item: YourItem

    var body: some View {
        VStack(alignment: .leading) {
            Text(item.text)
            HStack {
                Button(action: {
                    print("Like")
                }) {
                    Image(systemName: "heart.fill")
                }
                Button(action: {
                    print("Star")
                }) {
                    Image(systemName: "star.fill")
                }
            }
        }
        .buttonStyle(PlainButtonStyle())
    }
}

struct YourListView: View {
    @ObservedObject var dataSource = YourDataSource()

    var body: some View {
        List(dataSource.items) { item in
            YourItemView(item: item)
        }
        .navigationBarTitle("List example", displayMode: .inline)
        .edgesIgnoringSafeArea(.bottom)
    }
}

#if DEBUG
struct YourListView_Previews: PreviewProvider {
    static var previews: some View {
        YourListView()
    }
}
#endif

As said in the article, it also works with NavigationLinks. I hope it helped some of you 🤞🏻

5
votes

This is my simplest solution that is working for me (lo and behold, I'm building my first app in Swift and SwiftUI as well as this being my first post on SO):

Wherever you have buttons, add .buttonStyle(BorderlessButtonStyle())

Button(action:{}){
Text("Hello")
}.buttonStyle(BorderlessButtonStyle())

Then on your list, add .onTapGesture {return}

List{
Text("Hello")
}.onTapGesture {return}
0
votes

Instead of using a button try it with a gesture instead

Group {
    Text("Notify").padding(5).gesture(TapGesture().onEnded() {
            print("action2")
            })
        .padding()
        .background(Color.purple)
        .cornerRadius(5)
    }