I'm working on a iOS app (using SwiftUI) in which the user must tap an image to get a response. The image overlays another background image, so it intentionally has some transparency. In some of the images there is a lot of transparent space. This allows too much tappable area in "empty space". I would like to refine it so that only the visible part is responsive to the tap gesture.
As of right now, anywhere a user taps the gesture responds...even if the user taps in a transparent part of the image. I found a similar question here Make only visible parts of png clickable UIbutton swift, but it seems to deal with multiple images in a ZStack. Here is some code that I have:
Image("dog")
.resizable()
.scaledToFit()
.zIndex(1)
.clipped()
.gesture(simpleTap)
var simpleTap: some Gesture {
TapGesture()
.onEnded { _ in
playSound("dog.mp3")
}
}
The key here is to set the
contentShape
of the image to aShape
that represents the outline of the image.If your image is a static image, then you can just use an image editor to find the outline and export it to a vector graphics format. For example, in GIMP, you can select the non-transparent part of the image, convert selection to path, then export that path to SVG. (See What's the easiest way to turn the non-transparent parts of any image file into a single svg path?) Then you can read the SVG with something like PocketSVG, get a
CGPath
, and create a SwiftUIPath
from it.If the image is resizable, you should resize the path accordingly. You can create your own
Shape
to do this: