2

I need to add a UITapGestureRecognizer to multiple UILabel and they all need to go to the same function for handling.

What I have is this:

@IBOutlet weak var label_something: UILabel!
let tap = UITapGestureRecognizer(target: self, action: #selector(self.myFunction))
label_something.addGestureRecognizer(tap)

Recieved here:

@objc func myFunction(sender:UITapGestureRecognizer) { // Something... }

Working like a charm. Problem is that its only working with one UILabel (If adding addGestureRecognizer(tap) to multiple UIlabel it only works on the last one added)

So my question is:

How to achieve what I want to do here? Five different UILabels with tapRecognizer going to the same function

MHopstad
  • 333
  • 2
  • 16
  • How did you determine `myFunction(sender:)` called only for one label? If you tap on the other label, It didn't call. Did you check with log? – Mani Apr 25 '18 at 12:00
  • Yes, a simple print("hepp") in the function only showed when clicking the one that worked. – MHopstad Apr 25 '18 at 12:01
  • Could you see here some more code? ie how you assign the `label_something`? – Mani Apr 25 '18 at 12:02
  • 1
    Why are you using label instead of a buttons? – Vladislav Kovalyov Apr 25 '18 at 12:03
  • @Sourcey86 Where did you add gesture for all other labels? – Mani Apr 25 '18 at 12:05
  • I mean, you have to add gesture for other labels too. like `label_something1.addGestureRecognizer(tap) label_something2.addGestureRecognizer(tap) label_something3.addGestureRecognizer(tap).... etc` – Mani Apr 25 '18 at 12:06
  • @Mani Samle like above. Instead of only label_something.addGestureRecognizer(tap) I have 5 rows of this with the different labels. Everything is done the same. Not showed in example to shorten down the text. – MHopstad Apr 25 '18 at 12:07
  • did you create new Gesture or assigning the same gesture to all labels? – Mani Apr 25 '18 at 12:10

3 Answers3

6

UIGestureRecognizer is to be used with a single view, you have to create a new instance of UIGestureRecognizer

func setGesture() -> UITapGestureRecognizer {

     var myRecognizer = UITapGestureRecognizer()

     myRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.myFunction))
     return myRecognizer
}

label_something1.addGestureRecognizer(setGesture())    
label_something2.addGestureRecognizer(setGesture())
Ahmad F
  • 30,560
  • 17
  • 97
  • 143
a.masri
  • 2,439
  • 1
  • 14
  • 32
3

If you add new instance from UITapGestureRecognizer its will work fine, for example

let tap = UITapGestureRecognizer(target: self, action: #selector(self.myFunction))
label_1.addGestureRecognizer(tap)
let tap2 = UITapGestureRecognizer(target: self, action: #selector(self.myFunction))
label_2.addGestureRecognizer(tap)
A.Munzer
  • 1,890
  • 1
  • 16
  • 27
  • Are you sure, need to create new gesture for every label? – Mani Apr 25 '18 at 12:04
  • @Mani A gesture recognizer can only be attached to one view. The reason is because each recognizer can have it's own gesture state (one is being triggered and the others are untouched). – Crazyrems Apr 25 '18 at 12:06
  • i think yes, because if you use the same instance, it will be added for the last label. – A.Munzer Apr 25 '18 at 12:07
  • @Crazyrems ya got your point. after seeing this. https://stackoverflow.com/questions/4747238/can-you-attach-a-uigesturerecognizer-to-multiple-views – Mani Apr 25 '18 at 12:08
  • @Mani yes. Each label needs to get a tap gesture recognizer, i.e one `UITapGestureRecognizer` can be only assigned to single component, that's why the *last* label recognize the `tap`, it would automatically removed from the previous labels. However, all gestures can have the same selector method. – Ahmad F Apr 25 '18 at 12:10
  • @AhmadF Ya got it. see my comment above. I think, It should be answer for this question. – Mani Apr 25 '18 at 12:11
0

Each UIView needs its own recognizer, i have a little helper function for this case. Feel free to copy/paste.

private func addTapRecognizer(toView view: UIView) {
        let recognizer = UITapGestureRecognizer(target: self, action: #selector(didTapButton(sender:)))
        view.isUserInteractionEnabled = true
        view.addGestureRecognizer(recognizer)
    }

    @objc private func didTapButton(sender: UIGestureRecognizer) {
        guard let view = sender.view else {
            return
        }

        switch view {
        case self.imageView: // any view you want to check
        default:
            print(sender.debugDescription)
        }
     }