1

I'm having a bit of a problem with a UITapGestureRecognizer. I create it this way:

self.userInteractionEnabled = YES;

UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
tapRecognizer.cancelsTouchesInView = NO;
tapRecognizer.delaysTouchesBegan = YES;
tapRecognizer.delegate = self;
tapRecognizer.numberOfTapsRequired = 1;
tapRecognizer.numberOfTouchesRequired = 1;
[self addGestureRecognizer:tapRecognizer];

In the header file I also include and implement the shouldReceiveTouch: method like so:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    return YES;
}

I've looked through countless threads of people with similar problems and can't seem to find a solution. I've heard that if the view you're adding the gesture recognizer has subviews with userInteractionEnabled set to YES, that could possibly interfere with the tap recognition, so I also include this:

for(UIView *subview in self.subviews) {
    subview.userInteractionEnabled = NO;
}

Anyone know why the gesture recognizer doesn't work?


Edit:

Here are some details:

  • I'm adding the UITapGestureRecognizer to a UIView subclass.
  • I add the gesture recognizer in the subclass' initWithFrame: method.
  • I've verified that the gesture recognizer is being added by stepping through the portion of the code where it's actually added.
  • The view controller that contains this view does not have any gesture recognizers attached to it, but does implement touchesBegan, touchesMoved, and touchesEnded. However, according to this question, that the view controller implements those shouldn't affect the gesture recognition of the view.


Edit 2:

I've verified that there are no other views blocking the view with the gesture recognizer from receiving touches. I've also verified that the view is actually being added to the containing view controller's view. It seems like the problem's elsewhere.

Community
  • 1
  • 1
pasawaya
  • 11,515
  • 7
  • 53
  • 92
  • Does one of this view's parent objects have a gesture recognizer attached to it? – Brian Shamblen Dec 15 '13 at 04:44
  • @BrianShamblen - The view controller that the view is in doesn't have any gesture recognizers attached to it, but it does implement `touchesBegan:`, `touchesMoved:`, and `touchesEnded:`. – pasawaya Dec 15 '13 at 05:41
  • Can you try to set the background color of the view to red? If you can see the red view fine, set the background color for all the views inside your hierarchy, then you can tell if the view is overlapped – vodkhang Dec 15 '13 at 10:08

3 Answers3

2

Your set up should work, so I would guess that one of two things is happening. You may have forgotten to actually add this view to the ViewController's view, or there maybe another view placed on top of this view which is stealing the touches?

Kelly Bennett
  • 725
  • 5
  • 27
  • +1 for stealing touches - I've run into this several times; you think that a view above the current one wouldn't be in the way, but it is. Carefully inspect anything that may be above this view in the hierarchy. – Chris Dec 15 '13 at 06:24
  • Hmm. I've verified that I'm actually adding the view to the view controller's view. I'll try to see if there's anything placed on top of it. – pasawaya Dec 15 '13 at 06:25
  • It doesn't seem like anything is above it. I looped through all the view controller's view's subviews and logged all the subviews that intersect (turned out to be only one). Then I moved the view above that subview by calling `insertView:aboveSubview:` and double checked it by calling `bringSubviewToFront:` on the view. After all this the tap gesture recognizer still doesn't seem to work. – pasawaya Dec 15 '13 at 06:49
  • Theoretically you could still have a view above the view in question. To see a printout of the view hierarchy (with frames) you can pause execution of your app and paste this into the console: po [[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] recursiveDescription] – Kelly Bennett Dec 15 '13 at 07:13
  • You were right. There was a view covering up the entire screen. Removing that solved the problem. Thanks! – pasawaya Dec 15 '13 at 19:08
  • Awesome! Glad you figured it out :) – Kelly Bennett Dec 15 '13 at 19:21
  • Another possibility for those seeking answers: maybe you have a custom implementation of `point(inside:with:)` which is leaving those touches for a lower view. I had one of these in a video control overlay where we only wanted the child controls to be interactive. Easily forgotten, leading to head-scratching! – alex bird May 02 '23 at 12:21
0

Another possibility causing the problem is that the view on which the UITapGestureRecognizer is added is not big enough, so when you tap on the screen, the touch point is not located in the view's bounds.

0

Also make sure the UIView is not transparent. Set the background color to e.g. black. This solved the problem for me.

  • If the alpha value for the UIView is set to 0 (in Interface Builder or in code), the gesture recognizer will not fire. But as long as the alpha is not zero, even if the background color is set to "clear", the recognizer will work. Useful for making larger areas of the screen responsive to taps/other gestures. – W S Nov 28 '19 at 16:24