2

TL;DR: I want to re-solve in SwiftUI this classic (and solved in UIKit) problem: how to pass along, to views behind, touches in transparent parts. Some approaches:

  1. Figure out if tap point has alpha == 0
  2. Providing a Bézier path to contentShape()

E.g. I want taps in the transparent parts of the orange image to go through to the green image. The transparent areas may be non-connected, like the "holes" in these images.

screen shot

Approach 1

@objc func handleTap(_ tgr: UITapGestureRecognizer) {
    let p = tgr.location(in: self)
    if pointIsOpaque(p) {
        // Handle it now.
    } else {
        // Pass it through.
    }
}

Finding the pointIsOpaque() property is well-covered in

But it escapes me how to use this in SwiftUI — both deciding on pixel alpha, and how to pass events to the next view in the z-ordering. I'd rather use pure SwiftUI than wrapping with UIViewRepresentable.

Approach 2

There is an existing "solution"; it raises as many challenges as it solves. This is to provide a path to View.contentShape(). For connected transparent regions, this should be perfect — but how to calculate the path? The even-odd rule would help for simple disconnected regions. But what if the transparent part is a Cantor set? (JK, but it could be complicated.)

There is some info about calculating the opaque boundary:

For my project I might be able to pre-calculate boundaries using pygame. But doing transparent-hit-testing seems more direct.

Andrew Duncan
  • 3,553
  • 4
  • 28
  • 55
  • Hmm, I am not getting transparency fall-through, neither using plain `onTapGesture()` or `gesture(TapGesture())`. I was hoping it would "just work" but it doesn't. In the shown test app, the orange view handles all taps within its rect, even in the transparent parts. Do you have a reference about automatic fall-through? – Andrew Duncan Feb 19 '20 at 20:53
  • I'm going to split off the `contentShape()` approach to a separate question. Meanwhile, my Q about transparency-testing and tap delegation is still open. – Andrew Duncan Feb 19 '20 at 22:35
  • My mistake, it was about views, not raster images. – Asperi Feb 20 '20 at 02:40
  • I solved this problem using masks and `ContentShape()` in the following post. I am still wondering if i could somehow get automatic transparency fall-through. https://stackoverflow.com/questions/60310697/swiftui-path-as-contentshape-doesnt-line-up-with-image/60326455#60326455 – Andrew Duncan Feb 20 '20 at 18:35

0 Answers0