'SwiftUI overlay cancels touches

I have a button and I'd like to put a semi-transparent gradient overlay on top of it.

Button(action: {
  print("Pressed")
}) {
  Text("Press me")
}
.overlay(
  LinearGradient(
    gradient: Gradient(colors: [.clear, Color.black.opacity(0.3)]),
    startPoint: .top,
    endPoint: .bottom
  ).disabled(true)
)

Even though the gradient has disabled(true) it still eats the touches and doesn't forward them to the actual button. .allowsHitTesting(false) provides the same result.

Any idea what can be wrong?

Note: I know I can put the overlay just to Text("Press me") but I don't want it. (This is just example code showcasing the problem)


Edit: This issue is solved in Xcode 11.2 ✅



Solution 1:[1]

The following code works on Xcode 11.2 / iOS 13.2

struct TestButtonWithOverlay: View {
    var body: some View {
        Button(action: {
            print("Pressed")
        }) {
            Text("Press me")
                .padding()
        }
            
        .overlay(
            LinearGradient(
                gradient: Gradient(colors: [.clear, Color.black.opacity(0.3)]),
                startPoint: .top,
                endPoint: .bottom
            )
            .allowsHitTesting(false) // !!! must be exactly here
        )
    }
}

backup

Solution 2:[2]

When working with a ScrollView the correct fix is to use the .background content modifier on the ScrollView:

https://developer.apple.com/documentation/swiftui/form/background(alignment:content:)

It will as expected with your "background" appearing above the content of the ScrollView.

Example of using to create a shadow effect:

Shadow effect via .background content modifier demonstrated


Interesting note: On the simulator .overlay works with a ScrollView, but on a physical device only .background allows scrolling.

The physical device is on iOS 14, and the simulator is iOS 15, so it's possible it might have been a regression. Although apparently this issue dates back further than either.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Selali Adobor