Handling Touch Event in UILabel and hooking it up to an IBAction

97,571

Solution 1

Check it out:

UILabel *label = ...
label.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture =
      [[UITapGestureRecognizer alloc] initWithTarget:self 
                                              action:@selector(labelTap)];
[label addGestureRecognizer:tapGesture];

The trick is to enable user interaction.

Solution 2

UILabel inherits from UIView which inherits from UIResponder. All UIresponder objects can handle touch events. So in your class file which knows about your view (which contains the UIlabel) implement:

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event;

In interface builder set the UILabel's tag value. when touches occur in your touchesBegan method, check the tag value of the view to which the tag belongs:

UITouch *touch = [touches anyObject];

if(touch.view.tag == MY_TAG_VAL)
label.text = @"new text";

You connect your code in your class file with the UILabel object in interface builder by declaring your UILabel instance variable with the IBOutlet prefix:

IBOutlet UILabel *label;

Then in interface builder you can connect them up.

Solution 3

You can use a UIButton, make it transparent, i.e. custom type without an image, and add a UILabel on it (centered). Then wire up the normal button events.

Solution 4

Swift 3

You have an IBOutlet

@IBOutlet var label: UILabel!

In which you enable user interaction and add a gesture recognizer

label.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(userDidTapLabel(tapGestureRecognizer:)))
label.addGestureRecognizer(tapGesture)

And finally, handle the tap

func userDidTapLabel(tapGestureRecognizer: UITapGestureRecognizer) {
  // Your code goes here
}
Share:
97,571

Related videos on Youtube

wfbarksdale
Author by

wfbarksdale

Updated on May 22, 2020

Comments

  • wfbarksdale
    wfbarksdale almost 4 years

    Ok, so I have a UILabel created in interface builder that displays some some default text of "tap to begin".

    When the user taps the UILabel I want it to trigger an IBAction method: -(IBAction)next; which updates the text on the label to say something new.
    It would be really convenient if this allowed me to simply drag a connection from my method to my label and then select touch up inside, as with a button. but alas, no cigar.

    so anyways, I guess my question is, am I going to have to subclass UILabel to get this to work? Or is there some way I can drag a button over the label, but make it 0% opaque. Or is there a simpler solution I'm missing?

  • stitz
    stitz almost 14 years
    I agree, the custom button type should give you a UILabel type user experience.
  • midas06
    midas06 almost 14 years
    One note, you have to make sure you check "User Interaction Enabled" in interface builder, or this won't work.
  • midas06
    midas06 almost 14 years
    I hit one problem with this method. It worked fine when the view controller was loaded directly, but when i created a nav controller, pushed the controller containing the label to the nav controller and then displaying it, the touches don't seem to get to the label anymore. Any Ideas?
  • Remover
    Remover almost 14 years
    if it's the same view controller class that you're pushing it should work. sounds like there may be some other little problem. maybe start another question and post some code
  • Brian Moeskau
    Brian Moeskau over 13 years
    +1, nice and simple. I had tried this before by setting a normal button to opactiy 0 which did not work, but the tip to change the type to custom worked perfectly.
  • Eiko
    Eiko over 13 years
    The opacity will effect the button and all of its subviews, so opacity=0 will make the whole thing invisible.
  • Defragged
    Defragged over 12 years
    A similar method that doesn't require tags is to simply check if touch.view is equal to the outlet you set for the label. I prefer this, as it means I don't have to keep track of the tags.
  • James Boutcher
    James Boutcher over 11 years
    Yikes. This is a hack compared to the other solutions in this thread. Use a tap gesture recognizer on a label if you want to recognize a tap gesture on a label. (See how it reads like it was meant for this?)
  • kevinl
    kevinl almost 11 years
    great solution. I recommend that you don't set any tag to be 0 because clicking anywhere else has a tag value of 0. This is because your view will most likely have a tag value of 0. Otherwise, you can set the tag of your view to something like -1 and then you can use the tag value of 0 somewhere else i.e. a button
  • learner
    learner almost 10 years
    What if I have multiple labels? how might I differentiate which one was tapped?
  • thedjaney
    thedjaney almost 10 years
    @learner try the tag property. make sure to use labelTap: instead of labelTap. and use - (void) labelTap:(id)sender;.
  • h4labs
    h4labs about 9 years
    @thedjaney The sender is the UITapGestureRecognizer, not the UILabel
  • Admin
    Admin almost 8 years
    TapGestureRecognizer is not the same as touch up inside, and loses human interface conformance and accessibility.
  • Admin
    Admin almost 8 years
    This is a far, far better solution because buttons handle touchupinside rather than just taps (begin).
  • Eiko
    Eiko almost 8 years
    @JamesBoutcher Look at the date of this question. UIGestureRecognizer was brand new (on the iPhone a few days). If you wanted to target anything older, it was not available. Today, I consider it a valid alternative. Just use the method that shows the intents best - if it really behaves like a button, use a button; if it's just some "text with a custom action not meant to be clicked regularly" take a gesture recognizer.
  • DJTano
    DJTano almost 8 years
    @h4labs you can use UITapGestureRecognizer *tapGesture = sender; then get the label tag with tapGesture.view.tag
  • POSIX-compliant
    POSIX-compliant over 5 years
    I had to add @objc to userDidTapLabel to get this to work. Might be a swift 4 thing.