'SwiftUI UIView with Overlay cancels touch
I am stuck on this UI issue, working with SwiftUI and UIView.
Basically, overlay stops user interaction to follow through to the UIView.
Button(action: { print("hello") }){ Text("HERE") }
.overlay(
LinearGradient(
gradient: Gradient(colors: [.clear, Color.black.opacity(0.3)]),
startPoint: .top,
endPoint: .bottom
).allowsHitTesting(false))
Not working with UIView
struct ButtonView: UIViewRepresentable {
func makeUIView(context: Context) -> UIButton {
return UIButton(type: .close)
}
func updateUIView(_ uiView: UIButton, context: Context) {
}
}
ButtonView()
.overlay(
LinearGradient(
gradient: Gradient(colors: [.clear, Color.black.opacity(0.3)]),
startPoint: .top,
endPoint: .bottom
).allowsHitTesting(false))
Is anyone running into same trouble? Thanks!
Solution 1:[1]
I explored a few avenues, but I could not make the overlay pass through the hit test. I think it's a bug. However I got this workaround working with:
struct ButtonView: UIViewRepresentable {
let button = UIButton(type: .close)
func makeUIView(context: Context) -> UIButton { return button }
func updateUIView(_ uiView: UIButton, context: Context) { }
func makeCoordinator() -> Coordinator { Coordinator(self) }
class Coordinator: NSObject {
var parent: ButtonView
var count = 0
init(_ uiView: ButtonView) {
self.parent = uiView
super.init()
self.parent.button.addTarget(self, action: #selector(clickAction(_:)), for: .touchUpInside)
}
@objc func clickAction(_ sender: UIButton) {
print("---> clicked on button \(count)")
count += 1
}
}
}
and
let buttonView = ButtonView()
var body: some View {
buttonView
.overlay(LinearGradient(
gradient: Gradient(colors: [.clear, Color.black.opacity(0.3)]),
startPoint: .top,
endPoint: .bottom
).onTapGesture { self.buttonView.button.sendActions(for: .touchUpInside) })
}
Solution 2:[2]
I ran into this issue too. In my case, putting a SwiftUI placeholder Text over a UITextView representable blocks touch input, even with allowsHitTesting(false)
.
My solution-for-dummies was to put the placeholder Text underneath the UITextView, ensuring the latter has a nil backgroundColor
. Hopefully we'll see missing features like responder chain control come to SwiftUI, so we don't have to resort to using classic UIView elements.
Solution 3:[3]
Im my case work with .allowsHitTesting(false)
inside .overlay
method.
var body: some View {
PageView(pages: images)
.frame(maxWidth: .infinity, maxHeight: 250)
.overlay {
TextOverlay()
.allowsHitTesting(false)
}
}
Here PageView is UIPageViewController
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 | workingdog support Ukraine |
Solution 2 | Jiropole |
Solution 3 | Max |