SwiftUI can't tap in Spacer of HStack

I've got a List view and each row of the list contains an HStack with some text view('s) and an image, like so:

HStack{
    Text(group.name)
    Spacer()
    if (groupModel.required) { Text("Required").color(Color.gray) }
    Image("ic_collapse").renderingMode(.template).rotationEffect(Angle(degrees: 90)).foregroundColor(Color.gray)
}.tapAction { self.groupSelected(self.group) }

This seems to work great, except when I tap in the empty section between my text and the image (where the Spacer() is) the tap action is not registered. The tap action will only occur when I tap on the text or on the image.

Has anyone else faced this issue / knows a workaround?


Solution 1:

As I've recently learned there is also:

HStack {
  ...
}
.contentShape(Rectangle())
.onTapGesture { ... }

Works well for me.

Solution 2:

Why not just use a Button?

Button(action: { self.groupSelected(self.group) }) {
    HStack {
        Text(group.name)
        Spacer()
        if (groupModel.required) { Text("Required").color(Color.gray) }
        Image("ic_collapse").renderingMode(.template).rotationEffect(Angle(degrees: 90)).foregroundColor(Color.gray)
    }
}.foregroundColor(.primary)

If you don't want the button to apply the accent color to the Text(group.name), you have to set the foregroundColor as I did in my example.

Solution 3:

works like magic on every view:

extension View {
        func onTapGestureForced(count: Int = 1, perform action: @escaping () -> Void) -> some View {
            self
                .contentShape(Rectangle())
                .onTapGesture(count:count, perform:action)
        }
    }