1

Any idea why the Tap gesture on a UI Label will not fire?

I've tried using a delegate also but in its simplest form, for some reason it will just not hit the action method.

Is the UIView layer restricting this interaction?

class TestTextViewLabel : UIView {
    weak var testTextView: UITextView!
    weak var testLabel: UILabel!

    override init(frame: CGRect) {
        super.init(frame: frame)

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(testLabelTapped(_:)))

        let testUITextView: UITextView = {
            let textView = UITextView()
            textView.textColor = UIColor(hex: "#000")
            textView.translatesAutoresizingMaskIntoConstraints = false
            return textView
        }()

        let testUILabel: UILabel = {
            let label = UILabel()
            label.textColor = UIColor(hex: "#666666")!
            label.translatesAutoresizingMaskIntoConstraints = false

            label.addGestureRecognizer(tapGesture)
            label.isUserInteractionEnabled = true

            return label
        }()

        self.addSubview(testUITextView)
        self.addSubview(testUILabel)

        self.testTextView = testUITextView
        self.testLabel = testUILabel

        testUITextView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
        testUITextView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
        testUITextView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true

        testUILabel.topAnchor.constraint(equalTo: testUITextView.bottomAnchor, constant: 50).isActive = true
        testUILabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
        testUILabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    @objc func testLabelTapped(_ sender: UITapGestureRecognizer) {
        print("testLabelTapped")
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
fes
  • 2,465
  • 11
  • 40
  • 56
  • 1. You are giving leftAnchor and rightAnchor instead you should use leadingAnchor and trailingAnchor 2. You've given Top, Left and Right but the height of the UILabel is Zero as there is no text inside it. You need to either set some text to your label or give it static height.. so that it a trappable area can be formed. – Sahil Manchanda Feb 24 '19 at 17:45
  • https://stackoverflow.com/questions/27880607/how-to-assign-an-action-for-uiimageview-object-in-swift/53809261#53809261 check that it will work on Label, UIView, ImageView and child of UIView – Ravindra_Bhati Feb 25 '19 at 05:12

1 Answers1

1

I tried running your class and I was able to get the UILabel to fire after putting text into it. The tap gesture is only recognized within the view's bounds and since you didn't have any text in the UILabel, the bounds were zero giving you no place to click it. By default, if you put in text, the UILabel will automatically match those bounds. Here is my working code below:

class TestTextViewLabel : UIView {
    weak var testTextView: UITextView!
    weak var testLabel: UILabel!

    override init(frame: CGRect) {
        super.init(frame: frame)

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(testLabelTapped(_:)))

        let testUITextView: UITextView = {
            let textView = UITextView()
            textView.textColor = UIColor.black
            textView.translatesAutoresizingMaskIntoConstraints = false
            textView.text = "This is a text view"

            textView.backgroundColor = .clear
            return textView
        }()

        let testUILabel: UILabel = {
            let label = UILabel()
            label.textColor = UIColor(red:0.40, green:0.40, blue:0.40, alpha:1.0)
            label.translatesAutoresizingMaskIntoConstraints = false

            label.addGestureRecognizer(tapGesture)
            label.isUserInteractionEnabled = true

            label.text = "This is a UILabel view"

            return label
        }()

        self.addSubview(testUITextView)
        self.addSubview(testUILabel)

        self.testTextView = testUITextView
        self.testLabel = testUILabel

        testUITextView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
        testUITextView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
        testUITextView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true

        testUILabel.topAnchor.constraint(equalTo: testUITextView.bottomAnchor, constant: 50).isActive = true
        testUILabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
        testUILabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    @objc func testLabelTapped(_ sender: UITapGestureRecognizer) {
        print("testLabelTapped")
    }
}
CentrumGuy
  • 576
  • 1
  • 4
  • 16
  • I've tried cases where the UILabel has no text (not within a UIView like this, just in a ViewController) and it seems to fire. Have you tried a label text with no text, and just add a heightAnchor with constant of say 50? – fes Feb 24 '19 at 17:36
  • 1
    Yeah that could work too. As long as the bounds of the button are not zero then you should have a place to click. I recommend setting the background color of the uilabel to some color that stands out during debugging to see where the clickable area of the label is. – CentrumGuy Feb 24 '19 at 17:37