Tappable area expands with clipped Image

Hello!


I'm having a hard time finding a workaround for this SwiftUI bug. At least I think it is a bug as I cannot find anything related to it anywhere.

So I have the following code in a View:

ForEach((1...5), id: \.self) { index in
    HStack(spacing: 24) {
         Image("tallImage1200x1800")
              .resizable()
              .aspectRatio(contentMode: .fill)
              .frame(width: 150, height: 120)
              .clipped()
         Text("Random text")
    }
    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .leading)
    .background(Color.white)
    .clipShape(RoundedRectangle(cornerRadius: 15))
    .shadow(color: Color.black.opacity(Double(0.3)), radius: 1, x: 1, y: 1)
    .padding(.vertical, 6)
    .padding(.horizontal, 16)
    .frame(height: 120)
    .onTapGesture {
        print("\(index)")
    }
}


The problem is that if you now tap on the lower part of any of the HStacks you will actually get the index of the next card printed out. This clearly happens because the tappable area is expanded to the new top and bottom bounds of the resized image.

As a workaround I tried:

- adding an overlay view to the HStack and hook the tap gesture to it instead, but the same thing happens;

- adding a reversed zIndex to the views, so that the top-most view has the highest zIndex and the last one has the lowest zIndex, which seemed to have a part in the matter, as now if you tap on the upper part of the card you get the index of the previous box printed out;

- adding different modifiers to the HStack before the tap gesture listener to make sure the bounds stay in the 120 area, but the same thing happens.


Can anyone think of a workaround for this? Any input will be much appreciated.


Thank you!

This seems to be cause by an Image that's clipped with aspectRatio fill.
Able to reproduce in iOS 14 Beta 1 (18A5301v) and in Xcode Playground 12.0 beta (12A6159)
Filed Radar: FB7811062

Drag one of the images to notice the clipped area still appearing:
Code Block Swift
struct Home: View {
    let items = Array(repeating: UIImage(named: "TestImage.jpg")!, count: 10)
    var body: some View {
        ScrollView(.horizontal, showsIndicators: true) {
            HStack {
                ForEach(items, id: \.self) { item in
                    Image(uiImage: item)
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: 100, height: 180, alignment: .center)
                        .clipped()
                        .onDrag {
                            return NSItemProvider(object: NSString("Test"))
                        }
                }
            }
        }
    }
}


This bug is still apparent in Xcode 13 beta and most likely will be there on release.

A temporary workaround is to wrap the entire image inside a Button(action: label:), but this gives an undesirable down state effect in most cases. Furthermore, strangely enough, applying a .buttonStyle(...) seems to revert back to the original tap bug where the incorrect index is selected.

Did you try to use the contentShape() modifier.

.clipShape(#yourShape#) will clip the view but don't the modify the shape for hit testing.

.contentShape(#yourShape#) will defines the content shape for hit testing.

Tappable area expands with clipped Image
 
 
Q