How can I detect a double tap on a certain cell in UITableView
?
i.e. I want to perform one action if the user made a single touch and a
if([touch tapCount] == 1)
{
[self performSelector:@selector(singleTapRecevied) withObject:self afterDelay:0.3];
} else if ([touch tapCount] == 2)
{
[TapEnableImageView cancelPreviousPerformRequestsWithTarget:self selector:@selector(singleTapRecevied) object:self];
}
Use the performSelector to call a selector instead of using a timer. This solves the issue mentioned by @V1ru8.
According to @lostInTransit I prepared code in Swift
var tapCount:Int = 0
var tapTimer:NSTimer?
var tappedRow:Int?
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//checking for double taps here
if(tapCount == 1 && tapTimer != nil && tappedRow == indexPath.row){
//double tap - Put your double tap code here
tapTimer?.invalidate()
tapTimer = nil
}
else if(tapCount == 0){
//This is the first tap. If there is no tap till tapTimer is fired, it is a single tap
tapCount = tapCount + 1;
tappedRow = indexPath.row;
tapTimer = NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector: "tapTimerFired:", userInfo: nil, repeats: false)
}
else if(tappedRow != indexPath.row){
//tap on new row
tapCount = 0;
if(tapTimer != nil){
tapTimer?.invalidate()
tapTimer = nil
}
}
}
func tapTimerFired(aTimer:NSTimer){
//timer fired, there was a single tap on indexPath.row = tappedRow
if(tapTimer != nil){
tapCount = 0;
tappedRow = -1;
}
}
This solution is only works for UICollectionView or UITableView's cell.
First declare these variables
int number_of_clicks;
BOOL thread_started;
Then put this code in your didSelectItemAtIndexPath
++number_of_clicks;
if (!thread_started) {
thread_started = YES;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
0.25 * NSEC_PER_SEC),
dispatch_get_main_queue(),^{
if (number_of_clicks == 1) {
ATLog(@"ONE");
}else if(number_of_clicks == 2){
ATLog(@"DOUBLE");
}
number_of_clicks = 0;
thread_started = NO;
});
}
0.25 is the delay of between 2 clicks. I think 0.25 is perfect for detect this type of click. Now you can detect only one click and two clicks seperately. Good Luck
In your UITableView
subclass, do something like this:
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch* touch in touches) {
if (touch.tapCount == 2)
{
CGPoint where = [touch locationInView:self];
NSIndexPath* ip = [self indexPathForRowAtPoint:where];
NSLog(@"double clicked index path: %@", ip);
// do something useful with index path 'ip'
}
}
[super touchesEnded:touches withEvent:event];
}
Improvement for oxigen answer.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if(touch.tapCount == 2) {
CGPoint touchPoint = [touch locationInView:self];
NSIndexPath *touchIndex = [self indexPathForRowAtPoint:touchPoint];
if (touchIndex) {
// Call some callback function and pass 'touchIndex'.
}
}
[super touchesEnded:touches withEvent:event];
}
First define:
int tapCount;
NSIndexPath *tableSelection;
as class level variables in the .h file and do all the necessary setting up. Then...
- (void)tableView(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
tableSelection = indexPath;
tapCount++;
switch (tapCount) {
case 1: //single tap
[self performSelector:@selector(singleTap) withObject: nil afterDelay: .4];
break;
case 2: //double tap
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(singleTap) object:nil];
[self performSelector:@selector(doubleTap) withObject: nil];
break;
default:
break;
}
}
#pragma mark -
#pragma mark Table Tap/multiTap
- (void)singleTap {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"Single tap detected" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
tapCount = 0;
}
- (void)doubleTap {
NSUInteger row = [tableSelection row];
companyName = [self.suppliers objectAtIndex:row];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"DoubleTap" delegate:nil cancelButtonTitle:@"Yes" otherButtonTitles: nil];
[alert show];
tapCount = 0;
}