How to know that if the only visible area of a .png is touched in Xcode

I have imported a .png image into UIImageView in Xcode and what I want to make is when the image is touched, it will be hidden.

But my problem is that the png image contains transparent parts and when I touch on the transparent parts, the action goes on. I want the action to go on only when the visible part of the image is touched. How to solve the problem?

Swift or Objective-C


I have created a custom UIButton subclass that behaves exactly as you describe, have a look: https://github.com/spagosx/iOS-Shaped-Button-Swift

It's written in Swift, but it's easily convertible to Objective-c.

The approach is to get the pixel data from the touch point and to access the RGBA values, in this case we read A (alpha) and check if it is higher than our threshold.

Looking at a bit of code:

func alphaFromPoint(point: CGPoint) -> CGFloat {
    var pixel: [UInt8] = [0, 0, 0, 0]
    let colourSpace = CGColorSpaceCreateDeviceRGB()
    let alphaInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
    let context = CGContext(data: &pixel, width: 1, height: 1, bitsPerComponent: 8, bytesPerRow: 4, space: colourSpace, bitmapInfo: alphaInfo.rawValue)

    context?.translateBy(x: -point.x, y: -point.y)

    self.layer.render(in: context!)

    let floatAlpha = CGFloat(pixel[3])
    return floatAlpha
}

You can than take the floatAlpha value and compare it with your acceptable value of alpha:

    override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
        return self.alphaFromPoint(point) >= 100
    }

I have taken the liberty of updating 'Danny S's' answer to Swift 5 and removed extraneous code, bug fixed and added some additional clarity to the UX.

Here's the code:

https://github.com/ZoeESummers/SOXShapedTapView-Updated.git