SwiftUI - Two buttons in a List

Set the button style to something different from the default, e.g., BorderlessButtonStyle()

struct Test: View {
  var body: some View {
    NavigationView {
      List {
        ForEach([
          "Line 1",
          "Line 2",
        ], id: \.self) {
          item in
          HStack {
            Text("\(item)")
            Spacer()
            Button(action: { print("\(item) 1")}) {
              Text("Button 1")
            }
            Button(action: { print("\(item) 2")}) {
              Text("Button 2")
            }
          }
        }
        .onDelete { _ in }
        .buttonStyle(BorderlessButtonStyle())
      }
      .navigationBarItems(trailing: EditButton())
    }
    .accentColor(.red)
  }
}

On Xcode 12.5 I've had the same issue in SwiftUI, the full area of the list item being highlighted when tapped.

.buttonStyle(BorderlessButtonStyle()) does the job, and now the two custom button can be tapped separately on the list item.


I struggled with this issue for a while. Apple has made Button kind of special in SwiftUI. It can change depending on the context it's used. That is why we see this weird functionality when a Button is inside a List.

Fortunately, there are other ways using .tapAction or a TapGesture. Try out the code below.

var body: some View {
    HStack {
        Text(control.name)
        Spacer()
        Text("Action")
            .frame(width: 250 - 10)
            .padding(5)
            .background(Color(white: 0.9))
            .cornerRadius(10)
            .frame(width: 250)
            .tapAction {
                print("action1")
            }

        Image(systemName: "info.circle")
            .foregroundColor(.accentColor)
            .tapAction {
                print("action2")
            }
    }
}

or

var body: some View {
    HStack {
        Text(control.name)
        Spacer()
        Text("Action")
            .frame(width: 250 - 10)
            .padding(5)
            .background(Color(white: 0.9))
            .cornerRadius(10)
            .frame(width: 250)
            .gesture(TapGesture().onEnded() {
                print("action1")
                })

        Image(systemName: "info.circle")
            .foregroundColor(.accentColor)
            .gesture(TapGesture().onEnded() {
                print("action2")
            })
    }
}

Tags:

Swift

Swiftui