10

This is in a UILabel subclass I made, but it doesn't seem to work. It doesn't call "tappedOn" for some reason.

gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedOn)];
[self addGestureRecognizer:gesture];
[self setUserInteractionEnabled:YES];

Do you know why it might be?

Here is the tappedOn method:

-(void)tappedOn
{

NSLog(@"tapped");
if ([self.type isEqualToString: @"load"])
{
    [self.manager.manager loadSavedGameInRow:self.name];
}

if ([self.type isEqualToString: @"save"])
{
    [self.manager.manager saveGameInRow:self.name];
}
}
Horton Jackson
  • 255
  • 1
  • 4
  • 12

10 Answers10

22

For me it works:

first set this : [self setUserInteractionEnabled:YES];

then:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(method:)];
tap.numberOfTapsRequired = 1;

[self addGestureRecognizer:tap];
Magyar Miklós
  • 4,182
  • 2
  • 24
  • 42
Irfa
  • 221
  • 1
  • 3
4

I tried this code for my project and its working fine for me.

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureUpdated:)];
    tapGesture.delegate = self;
    tapGesture.numberOfTapsRequired = 1;
    tapGesture.numberOfTouchesRequired = 1;
    tapGesture.cancelsTouchesInView = NO;
    [[self view] addGestureRecognizer:tapGesture];

- (IBAction)tapGestureUpdated:(UIGestureRecognizer *)recognizer
{
    // Code to respond to gesture here
}
Manthan
  • 3,856
  • 1
  • 27
  • 58
  • I'm not using interface builder – Horton Jackson Sep 20 '13 at 11:35
  • Did you define your method the way i posted? Now put breakpoint and check. your Method will definitely get called. – Manthan Sep 20 '13 at 11:37
  • i tried it but it didn't work for some reason. this is so strange – Horton Jackson Sep 20 '13 at 11:48
  • Did you define delegate in your .h file? You have to define that. look if you are missing it. – Manthan Sep 20 '13 at 11:50
  • yep i have . So "IBAction" doesn't effect the program if you aren't using interface builder? – Horton Jackson Sep 20 '13 at 11:53
  • No, it does effect. You can give an action to a button programmatically. – Manthan Sep 20 '13 at 12:11
  • it strangely started working when i put an empty one of these in the code -`(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { }` The tappedOn method is still the one being called, though. – Horton Jackson Sep 20 '13 at 12:32
  • 2
    `IBAction` just exposes a method to Interface Builder so you can connect a control to it. I believe otherwise, it is equivalent to `void`. – Zev Eisenberg Sep 20 '13 at 12:44
  • @HortonJackson: did you put ":" in your code after (tappedOn)? you should write(tappedOn:) for method to get called. – Manthan Sep 20 '13 at 12:54
  • Setting the delegate does nothing here. The tap gesture delegate is only used for fine-tuning the behavior of gesture handling. See: https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIGestureRecognizerDelegate_Protocol/index.html#//apple_ref/occ/intf/UIGestureRecognizerDelegate – eremzeit Mar 31 '15 at 08:59
4

In the off chance that your label is outside the bounds of its superview, touch handling will likely not work. Worth a check, since your gesture recognizer code seems correct.

One more thing to try: are you sure your code to add the gesture recognizer to the view is being run? What method are you in when you call it?

Zev Eisenberg
  • 8,080
  • 5
  • 38
  • 82
2

I found a good example for you: stackoverflow link

This is a step by step guide on how to implement gesture recognizers in your class:

Conform your class to UIGestureRecognizerDelegate protocol.

Instantiate the gesture recognizer. For example, to instantiate a UITapGestureRecognizer, we will do:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapFrom:)];

Here, action is the selector which will handle the gesture. Here, our selector handleTapFrom will look something like:

- (void) handleTapFrom: (UITapGestureRecognizer *)recognizer
{
    //Code to handle the gesture
}

The argument to the selector is the gesture recognizer. We can use this gesture recognizer to access its properties, for example, we can find the state of the gesture recognizer, like, UIGestureRecognizerStateBegan, UIGestureRecognizerStateEnded, etc.

Set the desired properties on the instantiated gesture recognizer. For example, for a UITapGestureRecognizer, we can set the properties numberOfTapsRequired, and numberOfTouchesRequired.

Add the gesture recognizer to the view you want to detect gestures for. In our sample code (I will be sharing that code for your reference), we will add gesture recognizers to an imageView with the following line of code:

[self.imageView addGestureRecognizer:tapGestureRecognizer];

After adding the gesture recognizer to the view, set the delegate for the gesture recognizer, i.e. the class which will handle all the gesture recognizer stuff. In our sample code, it would be like:

tapGestureRecognizer.delegate = self;

Note: Assign the delegate after adding the gesture recognizer to the view. Otherwise, the action method won’t be called.

Community
  • 1
  • 1
Magyar Miklós
  • 4,182
  • 2
  • 24
  • 42
2

Try this:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {

    return true

}

I use Swift because I'm not familiar with ObjC. Return true is guaranteed to allow simultaneous recognition.

Sometimes you may want to set tup some constraints to avoid conflict, like:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    if gestureRecognizer == singleTapShowHideRecognizer {
        return true
    }
    return false
}
ilovecomputer
  • 4,238
  • 1
  • 20
  • 33
1
gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedOn:)];
[self.view addGestureRecognizer:gesture];
self.UserInteractionEnabled=TRUE;

Add your method like this

- (void) tappedOn:(UIGestureRecognizer*)sender
{
}

Try this one

Jitendra
  • 5,055
  • 2
  • 22
  • 42
  • what' sthe exact problem – Jitendra Sep 20 '13 at 11:25
  • 1
    This won't work, because if you got a method with parameter, must have ":" at the end of the selector. action:@selector(tappedOn:). (void)tappedOn:(UITapGestureRecognizer*)sender method got a parameter: (UITapGestureRecognizer*)sender – Magyar Miklós Sep 20 '13 at 12:27
  • This worked for me. I had a similar jig, I also added the UIGestureRecognizerDelegate, but I don't think it would make much of difference. The problem for me was that my object didn't have the userInteractionEnabled set to true. – Septronic Dec 10 '15 at 19:42
1

Looks like it should be in order... but have you forgotten your type in front of "gesture"? See below, and note the added UITapGestureRecognizer before your code:

UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedOn)];
[self addGestureRecognizer:gesture];
[self setUserInteractionEnabled:YES];

For more infos, see this answer about how to make a label clickable.

Community
  • 1
  • 1
siege_Perilous
  • 1,109
  • 9
  • 8
0

Not sure if this helps but to receive touch events exclusively use setExclusiveTouch:

gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedOn)];
[self addGestureRecognizer:gesture];
[self setUserInteractionEnabled:YES];
[self setExclusiveTouch:YES];
βhargavḯ
  • 9,786
  • 1
  • 37
  • 59
  • This won't work, because if you got a method with parameter, must have ":" at the end of the selector. action:@selector(tappedOn:). (void)tappedOn:(UITapGestureRecognizer*)sender method got a parameter: (UITapGestureRecognizer*)sender – Magyar Miklós Sep 20 '13 at 12:31
  • @incmiko If you look at implementation of method in question, it is custom method without parameter. But having ":" after selector is necessary in general for GestureRecognizer. Anyways my focus was on setExclusiveTouch: – βhargavḯ Sep 20 '13 at 12:36
0

It should work. It seems that you added the gesture inside the label subclass code. Are you sure you put in both initWithFrame: and initWithCoder: methods? because the two inits could be called independently based on the fact that you instantiate the label using a XIB or programatically.

Example:


@implementation MyLabel

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addGesture];
   }
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if(self) {
        [self addGesture];
    }
    return self;
}

-(void)addGesture {
    UITapGestureRecognizer *_g = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(myTap:)];
    [self addGestureRecognizer:_g];
    [self setUserInteractionEnabled:YES];

}

viggio24
  • 12,316
  • 5
  • 41
  • 34
0

I've had a similar frustrating problem - the solution was to make sure that the parent views of your view also have their "User interaction enabled" property set to true. You can set that through IB under "View" => "Interaction".

ArturT
  • 92
  • 1
  • 2