Re: [cocoaheadsau] Detect double tap on UITableViewCell?

1,735 views
Skip to first unread message

Tony Arnold

unread,
Jul 15, 2012, 12:58:00 AM7/15/12
to cocoah...@googlegroups.com
Hi Alex,

On 15/07/2012, at 10:54 AM, Alex M <oleksand...@gmail.com> wrote:

I was wondering what is the best way to detect a double tap on a UITableViewCell?

At the moment I added a UITapGestureRecognizer for the double tap gesture and added it to the UITableView. I found that it never got called because the default method didSelectRowAtIndexPath method always had priority so I added a UITapGestureRecognizer for a single tap. I found this still didn't work because the default didSelectRowAtIndexPath method still had priority over my gesture recognizer. In the end I set singleTap.cancelsTouchesInView and singleTap.delaysTouchesBegan to YES. This did the trick and I now have both single and double tap gestures on my UITableView (I then use UITableView's indexPathForRowAtPoint method to detect which row has been tapped).

Is this right? Is there a better way? All I'm after is for a single tap on a cell to retain it's default action of segueing to another view but when double tapped a the segue doesn't happen and a custom method is called.

Thanks for any help/advise you can provide. :)

You'll probably need to spelunk into the cell's existing gesture recognisers, find the default tap gesture and use the UIGestureRecognizer method 'requireGestureRecognizerToFail:' on it, specifying your double-tap gesture as the 'otherGestureRecognizer' parameter.

Before you go that far, have you tried just not implementing the 'didSelectRowAtIndexPath:' delegate method in your UITableViewDelegate?

-t



----------
Tony Arnold
http://thecocoabots.com/

Oliver Jones

unread,
Jul 15, 2012, 5:12:14 AM7/15/12
to cocoah...@googlegroups.com
I don't think UITableView or UITableViewCell actually uses gesture recognizers for this purpose.  The only recognizers I can find relate to the UIScrollView and long press on a UITableViewCell's contentView.

The UITableViewCell is a delegate for the contentView's UILongPressGestureRecognizer, but not for taps.

It would be nice if UIKit classes adopted gesture recognizers more universally.

I think the tap handling in UITableView is controlled with standard touchesBegan et al.  There are also UIScrollView touch event handling methods like:

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view;
- (BOOL)touchesShouldCancelInContentView:(UIView *)view;

You may be able to use these in combination with touchesBegan etc to recognise the double tap.  But this might get messy.  I actually think Alex was probably on to the right path. Or something like the right path. Replace all the tap handling in on UITableViewCells with gesture some gesture recognizers. 

However the right way to get a double tap gesture recognizer and single tap gesture recognizer to co-operate is actually to make the single tap recognizer to require that the double tap has failed with:

// create a relationship with another gesture recognizer that will prevent this gesture's actions from being called until otherGestureRecognizer transitions to UIGestureRecognizerStateFailed
// if otherGestureRecognizer transitions to UIGestureRecognizerStateRecognized or UIGestureRecognizerStateBegan then this recognizer will instead transition to UIGestureRecognizerStateFailed
// example usage: a single tap may require a double tap to fail
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;

Regards

Oliver Jones

unread,
Jul 15, 2012, 5:21:18 AM7/15/12
to cocoah...@googlegroups.com
On 15/07/2012, at 2:58 PM, Tony Arnold wrote:

--
You received this message because you are subscribed to the Google Groups "Australian Cocoaheads" group.
To post to this group, send email to cocoah...@googlegroups.com.
To unsubscribe from this group, send email to cocoaheadsau...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cocoaheadsau?hl=en.

Rogerio de Paula Assis

unread,
Jul 15, 2012, 5:37:25 AM7/15/12
to cocoah...@googlegroups.com
Hi Alex,

Try setting delayTouchesBegan == YES to your doubleTapGestureRecognizer

        UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapOnCell:)];
        doubleTapGesture.numberOfTapsRequired = 2;
        doubleTapGesture.delaysTouchesBegan = YES;
        [self.contentView addGestureRecognizer:doubleTapGesture];    

From the documentation:

"When the value of this property is NO (the default), views analyze touch events in UITouchPhaseBegan and UITouchPhaseMoved in parallel with the receiver. When the value of the property is YES, the window suspends delivery of touch objects in the UITouchPhaseBegan phase to the view. If the gesture recognizer subsequently recognizes its gesture, these touch objects are discarded. If the gesture recognizer, however, does not recognize its gesture, the window delivers these objects to the view in a touchesBegan:withEvent: message (and possibly a follow-up touchesMoved:withEvent: message to inform it of the touches’ current locations). Set this property to YES to prevent views from processing any touches in the UITouchPhaseBegan phase that may be recognized as part of this gesture."

Let us know if that works.
Cheers,
Rog

Rogerio de Paula Assis



On 15/07/2012, at 10:54 AM, Alex M wrote:

I was wondering what is the best way to detect a double tap on a UITableViewCell?

At the moment I added a UITapGestureRecognizer for the double tap gesture and added it to the UITableView. I found that it never got called because the default method didSelectRowAtIndexPath method always had priority so I added a UITapGestureRecognizer for a single tap. I found this still didn't work because the default didSelectRowAtIndexPath method still had priority over my gesture recognizer. In the end I set singleTap.cancelsTouchesInView and singleTap.delaysTouchesBegan to YES. This did the trick and I now have both single and double tap gestures on my UITableView (I then use UITableView's indexPathForRowAtPoint method to detect which row has been tapped).

Is this right? Is there a better way? All I'm after is for a single tap on a cell to retain it's default action of segueing to another view but when double tapped a the segue doesn't happen and a custom method is called.

Thanks for any help/advise you can provide. :)

--
You received this message because you are subscribed to the Google Groups "Australian Cocoaheads" group.
To view this discussion on the web visit https://groups.google.com/d/msg/cocoaheadsau/-/xhfLqWLGgn0J.

kylebuttress

unread,
Jul 15, 2012, 6:13:32 AM7/15/12
to cocoah...@googlegroups.com
UITableViewCell inherits from UIView so you could you possible subclass UITableViewCell  view and use - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

this could lead onto other way to achieve what you are looking to do.

Kyle Buttress

unread,
Jul 15, 2012, 6:02:28 AM7/15/12
to cocoah...@googlegroups.com
UITableViewCell inherits from UIView so you could you possible subclass UITableViewCell  view and use - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

this could lead onto other way to achieve what you are looking to do.


On 15/07/2012, at 10:54 AM, Alex M wrote:

I was wondering what is the best way to detect a double tap on a UITableViewCell?

At the moment I added a UITapGestureRecognizer for the double tap gesture and added it to the UITableView. I found that it never got called because the default method didSelectRowAtIndexPath method always had priority so I added a UITapGestureRecognizer for a single tap. I found this still didn't work because the default didSelectRowAtIndexPath method still had priority over my gesture recognizer. In the end I set singleTap.cancelsTouchesInView and singleTap.delaysTouchesBegan to YES. This did the trick and I now have both single and double tap gestures on my UITableView (I then use UITableView's indexPathForRowAtPoint method to detect which row has been tapped).

Is this right? Is there a better way? All I'm after is for a single tap on a cell to retain it's default action of segueing to another view but when double tapped a the segue doesn't happen and a custom method is called.

Thanks for any help/advise you can provide. :)

Oliver Jones

unread,
Jul 15, 2012, 6:18:53 AM7/15/12
to cocoah...@googlegroups.com
Using hitTest is not the right way to go.  It is intended for entirely different purposes.

Regards

Cameron Barrie

unread,
Jul 15, 2012, 6:32:21 AM7/15/12
to cocoah...@googlegroups.com
And UIView inherits from UIResponder which is where you'll find
- touchesBegan:withEvent:
- touchesEnded:withEvent:
- touchesCancelled:withEvent:

This is what UITableViewCell appears to use to delegate back to your table view delegate. You can find that by setting a symbolic breakpoint on those methods on a UITableViewCell, or by create a UITableViewCell subclass and over-riding these methods.

You could manage a bit of this stuff by over-riding these methods in a custom subclass of UITableViewCell. Forward to super for a single tap, and do what you want for a double tap. It's not using gesture recognisers, which kinda sucks though.

-C
Reply all
Reply to author
Forward
0 new messages