[SwiftUI] How can you use onTapGesture for the entire row in a ForEach loop?

May 14, 20242 min read#swift, #ios, #swiftui

While working on a new feature for my QuickDrop app, I encounter an intersting challenge regarding to the HStack.

The clickable area is not the entire row, but only where the title text is. The empty space is not clickable. This is a very bad user experience:

This is the code I have to render the above UI.

ForEach(shellScripts, id: \.self) { shellScript in
    HStack {
        Text(shellScript.shellScript.name)
        Spacer()
        if shellScript == shellScriptRow {
            Image(systemName: "checkmark").foregroundStyle(.green)
        }
    }
    .onTapGesture {
      // handle the tap gesture
    }
}

Luckily, there is very simple fix that people have suggested to me via X, simply adding .contentShape(.rect) modifier to the HStack

The improved code should be

ForEach(shellScripts, id: \.self) { shellScript in
    HStack {
        Text(shellScript.shellScript.name)
        Spacer()
        if shellScript == shellScriptRow {
            Image(systemName: "checkmark").foregroundStyle(.green)
        }
    }
    .contentShape(.rect)
    .onTapGesture {
      // handle the tap gesture
    }
}

The result behaviour is what I expected:

Quick Drop logo

Profile picture

Personal blog by An Tran. I'm focusing on creating useful apps.
#Swift #Kotlin #Mobile #MachineLearning #Minimalist


© An Tran - 2024