RjC
RjC

Reputation: 827

How to create just one tapGestureRecognizer for several UILabels?

I am trying (and failing) to create just one tapGestureRecognizer to use on several UILabels.

Right now I am creating for every label in viewDidLoad a separate tapGestureRecognizer and adding it to the appropriate label. I ran into this problem because every touch should obviously call a different function.

This is how I create them:

@IBOutlet weak var buttonOne: UILabel!
@IBOutlet weak var buttonTwo: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

        //tapGestureRecognizer for buttonOne

        buttonOne.isUserInteractionEnabled = true
        let oneGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MainViewController.buttonOneAction))
        buttonOne.addGestureRecognizer(oneGestureRecognizer)

        //tapGestureRecognizer for buttonTwo

        buttonTwo.isUserInteractionEnabled = true
        let twoGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MainViewController.buttonTwoAction))
        buttonTwo.addGestureRecognizer(twoGestureRecognizer)

        ...

They work fine, but how and where could I create just one tapGestureRecognizer and add it in viewDidLoad to each label with a different action?

Upvotes: 2

Views: 373

Answers (2)

Leo Dabus
Leo Dabus

Reputation: 236340

As already mentioned in comments by @Duncan C you can switch the gesture recognizer view as follow:

class ViewController: UIViewController {

    @IBOutlet weak var buttonOne: UILabel!
    @IBOutlet weak var buttonTwo: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        [buttonOne, buttonTwo].forEach {
            $0?.isUserInteractionEnabled = true
            $0?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapGesture)))
        }
    }

    @objc func tapGesture(_ gesture: UITapGestureRecognizer) {
        guard let label = gesture.view as? UILabel else { return }
        switch label {
        case buttonOne: print("buttonOne")
        case buttonTwo: print("buttonTwo")
        default: break
        }
    }
}

Upvotes: 2

Duncan C
Duncan C

Reputation: 131408

Just create one per label.

The alternative is to create a single tap gesture recognizer that you attach to the common superview of all target views, and write a BUNCH of code that does hit-testing to figure out if the tap landed on any of your labels, and if so, which one, and dispatches the desired method for that label.

However, that's the whole point of tap gesture recognizers. You'd probably spend several days developing a bunch of code that has no benefits over using multiple tap gesture recognizers.

Upvotes: 1

Related Questions