Mark
Mark

Reputation: 1454

Increasing hit area for UITapGestureRecognizer on UILabel

I'm trying to increase the hit area of a UITapGestureRecognizer on a UILabel object. This answer suggests overriding hitTest on the UILabel:

class PaddedLabel: UILabel {
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        print("hitTest called")
        let padding: CGFloat = 20.0
        let extendedBounds = bounds.insetBy(dx: -padding, dy: -padding)
        return extendedBounds.contains(point) ? self : nil
    }
}

However, the problem is that hitTest is not even called unless I'm actually tapping on the object, and not somewhere close to it. Therefore, extending the bounds seems to be useless.

The label is one of a few inside a UIStackView:

let label = PaddedLabel()
let gs = UITapGestureRecognizer(target: self, action: #selector(ThisViewController.handleTap(_:)))
label.addGestureRecognizer(gs)
label.isUserInteractionEnabled = true
stackView.addArrangedSubview(label)

How do I make this work?

Upvotes: 1

Views: 654

Answers (1)

Omer Faruk Ozturk
Omer Faruk Ozturk

Reputation: 1852

You can edit PaddedLabel like below to set insets:

class PaddedLabel: UILabel {
    
    var textInsets = UIEdgeInsets.zero {
        didSet { invalidateIntrinsicContentSize() }
    }

    override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect {
        let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
        let invertedInsets = UIEdgeInsets(top: -textInsets.top,
                                          left: -textInsets.left,
                                          bottom: -textInsets.bottom,
                                          right: -textInsets.right)
        return textRect.inset(by: invertedInsets)
    }

    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: textInsets))
    }
}

and set textInsets to enlarge its tappable area.

label.textInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)

enter image description here

enter image description here

Upvotes: 3

Related Questions