15

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)
        }
    }
}
Reedy
  • 1,866
  • 2
  • 20
  • 23
  • 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 Sep 03 '19 at 11:03
  • Yes i feel like this might be the solution for now, SwiftUI certainly is not production ready yet. – Reedy Sep 04 '19 at 07:35
  • Do you need a hand for that? – Mojtaba Hosseini Sep 04 '19 at 07:36
  • ive got two thanks – Reedy Sep 04 '19 at 08:41
  • 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 Mar 10 '21 at 20:37

3 Answers3

37

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

Rémi B.
  • 2,410
  • 11
  • 17
  • 1
    Great answer. I want to add that this also seems to work if you move `.buttonStyle(PlainButtonStyle())` out of the `YourItemView` struct itself and place it in the `YourListView` struct after the line `YourItemView(item: item)` – Rillieux Dec 05 '21 at 15:52
  • Amazing... It works like a charm. – Li Jin Dec 14 '21 at 14:50
  • Great answer, thanks! – krlbsk Mar 15 '22 at 07:45
8

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}
theSpuka
  • 131
  • 1
  • 2
0

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)
    }
yawnobleix
  • 1,204
  • 10
  • 21
  • 1
    Defeats the point of a button, in addition you wont get the nice button animations you get for free e.g. highlight on touch etc. – Reedy Sep 04 '19 at 07:36