I have a List and in each row I put a button at the left end and a text label on the right next to it. I want this button to have an action and the entire row to also have a tap gesture. So how can I properly distinguish between the gestures so that when the use taps the button it does the action of the button, and when the user tap anywhere else in the row, it does the tap gesture of the row?
Here is my code for now:
List {
ForEach(items) { item in
HStack {
Button {
buttonAction()
} label: {
Image(systemName: "circle.fill")
}
Text("Row Title")
}
.onTapGesture {
rowAction()
}
}
}
Now, when I tap the button or the text it does the rowAction()
, whereas when I tap other places in the row it does the buttonAction()
.
2
Answers
This should do it:
If you add a
.border(.blue)
to your HStack, you’ll notice that it doesn’t quite cover the entire row – and is therefore not tappable.Strangely, if you add a
.border(.red)
to your Button, you’ll notice that it also doesn’t cover the entire row, but the tappable area of the button expands beyond the size of its elements (so the red border doesn’t actually show the tappable button area).While at it, add a green border to the Text to better visualize everything:
Text("Row Title").border(.green)
To fix everything:
With the spacer added, you will see the expanded area of the tappable HStack, shown by the blue border.
The entire code:
Note: I left the borders in there for visualization purposes, but they’re not part of the solution. Remove them at will.