7
votes

I've set up a UITableView with a double-tap UITapGestureRecognizer. But attempts to double-tap a cell by the user just launches didSelectRowAtIndexPath twice. Are these two supposed to work together?

(i'm aware i could use a single tap gesture recognizer in place of the built-in behavior of didSelectRowAtIndexPath, but here's the problem with that: the cell also has a button that I can't press anymore when i add the single tap gesture recognizer. Also, I've seen examples on SO of users building double tap functionality into didSelectRowAtIndexPath, but isn't that a bit too much of a hack?)

4
I wanted a similar feature. Even after setting cancelsTouchesInView and delaysTouchesBegan I couldn't invoke the double tap handler.Anupdas

4 Answers

2
votes

You can use a single-tap gesture recognizer in place of didSelectRowAtIndexPath, even if there is a button in the cell. You just need to check if the touch location is inside the UIButton's view or not in order to handle both cases. Hope that Helps!

12
votes

More info about Kris' answer:

  • cancelsTouchesInView
  • delaysTouchesBegan
  • delaysTouchesEnded

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIGestureRecognizer_Class/Reference/Reference.html

In my case I had a problem when adding 2 tap gestures to a UIImageView that was on a custom UITableViewCell. What happened was the didSelectRowAtIndexPath: was called when you tap/double tap on the UIImageView. When I had only one tap gesture, the didSelectRowAtIndexPath: was not called (and for me, that was the right behavior.

To prevent the didSelectRowAtIndexPath: from being called when using two tap gestures (single/double tap), I added this code to the first tap gesture (the single one):

tapGesture.cancelsTouchesInView = YES;
tapGesture.delaysTouchesBegan = YES;

After this change, a tap/double on the UIImageView (on top of the custom cell) did not trigger the didSelectRowAtIndexPath:

5
votes

Looks like I can get didSelectRowAtIndexPath and the double tap gesture recognizer to play together nicely using the delaysTouchesBegan and cancelsTouchesInView properties of the gesture recognizer.

The other option described by @MSgambel seems to work equally well.

1
votes

I tested the "delayTouchesBegan" method with double taps but I found that the single tap received by the table is then delayed, making the table interaction less responsive to the user, and perhaps annoying.

My solution is a bit pedestrian but I use a timer to detect taps in method didSelectRowAtIndexPath. I record the tap count of "1" for the first tap, and if the user does not tap again with 0.2 seconds it displays the item selected. If the user tapped within 0.2 seconds for tap count "2" then I display another item (an action sheet). I reset the tap count each time.

This method uses more code, but provides quick response from the interface and the user does not need to know what is happening behind the scenes - just that the UI is responsive.