UITapGestureRecognizer breaks UITableView didSelectRowAtIndexPath UITapGestureRecognizer breaks UITableView didSelectRowAtIndexPath ios ios

UITapGestureRecognizer breaks UITableView didSelectRowAtIndexPath


Ok, finally found it after some searching through gesture recognizer docs.

The solution was to implement UIGestureRecognizerDelegate and add the following:

#pragma mark UIGestureRecognizerDelegate methods    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{  if ([touch.view isDescendantOfView:autocompleteTableView]) {                // Don't let selections of auto-complete entries fire the     // gesture recognizer    return NO;  }          return YES;}

That took care of it. Hopefully this will help others as well.


The easiest way to solve this problem is to:

UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc]     initWithTarget:self action:@selector(tap:)];[tapRec setCancelsTouchesInView:NO];

This lets the UIGestureRecognizer recognize the tap and also pass the touch to the next responder. An unintended consequence of this method is if you have a UITableViewCell on-screen that pushes another view controller. If the user taps the row to dismiss the keyboard, both the keyboard and the push will be recognized. I doubt this is what you intend, but this method is adequate for many situations.

Also, expanding on Robert's answer, if you have a pointer to the tableview in question, then you can directly compare its class instead of having to convert to a string and hope Apple doesn't change the nomenclature:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer      shouldReceiveTouch:(UITouch *)touch{    if([touch.view class] == tableview.class){        return //YES/NO    }    return //YES/NO}

Remember, you must also declare the UIGestureRecognizer to have a delegate with this code in it.


Set cancelsTouchesInView of your recognizer to false. Otherwise, it "consumes" the touch for itself, and does not pass it on to the table view. That's why the selection event never happens.

for example in swift

let tapOnScreen: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "CheckTheTime")tapOnScreen.cancelsTouchesInView = falseview.addGestureRecognizer(tapOnScreen)