Multiple buttons in SwiftUI List rows
In SwiftUI, when a Button
is placed inside a List
row, the framework automatically extends its tap area to cover the entire row. This behavior occurs when the button is assigned the default automatic
style, which allows SwiftUI to determine the most appropriate behavior based on context. In the case of List
, this means the row itself becomes tappable. This can introduce unintended behavior when multiple buttons are present in the same row.
Consider the following example, where without an explicitly assigned button style, tapping anywhere within the row will trigger both buttons simultaneously.
List(1...10, id: \.self) { item in
HStack {
Text("Item \(item)")
Spacer()
Button("Edit") {
print("Edit tapped for item \(item)")
}
Button("Delete") {
print("Delete tapped for item \(item)")
}
}
}
To ensure that each button behaves independently and responds only when directly tapped, we need to explicitly set a button style other than automatic
.
List(1...10, id: \.self) { item in
HStack {
Text("Item \(item)")
Spacer()
Button("Edit") {
print("Edit tapped for item \(item)")
}
Button("Delete") {
print("Delete tapped for item \(item)")
}
}
}
.buttonStyle(.borderless)
Since SwiftUI styles are applied to the environment and propagate down the view hierarchy, all buttons within the list inherit the borderless
style in the example above.
By explicitly specifying a button style, SwiftUI no longer applies the row-wide tap handling. Instead, each button retains its intended behavior, responding only when tapped within its actual bounds.