How can I make UIButton respond to touch on the transparent areas of a PNG image?

Just to follow on the suggestion by Caleb to override hitTest and taking inspiration from Soroush Khanlou, this makes any UIButton subclass respond to any touch that happens on the frame:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    guard
        isUserInteractionEnabled,
        !isHidden,
        alpha >= 0.01,
        self.point(inside: point, with: event)
    else {return nil}

    for subview in subviews.reversed() {
        let convertedPoint = subview.convert(point, from: self)
        if let candidate = subview.hitTest(convertedPoint, with: event) {
            return candidate
        }
    }

    return self
}

UIButton ignores touch if you touch it where there's no image alpha. Can I change it to respond to touch on its entire bounds?

One easy way that I think still works is to set the background color to something that's only mostly transparent. An alpha that's very small but still greater than 0.1 should look transparent but still respond to touches.

Otherwise, yes, you can override -hitTest:withEvent: such that it returns YES even if the touched area is transparent.


I actually do this all the time where I put the image with transparent background into a UIImageView and then put a UIButton with its backgroundColor set to [UIColor clearColor] on top of the image. This way, especially with small images, I can make the "invisible" button larger and easier to press for the user.