Как я могу обнаружить двойное нажатие на определенную ячейку в UITableView? - PullRequest
34 голосов
/ 23 июня 2009

Как я могу обнаружить двойное нажатие на определенную ячейку в UITableView?

т.е. Я хочу выполнить одно действие, если пользователь сделал одно касание, и другое, если пользователь сделал двойное касание? Мне также нужно знать индексный путь, где было сделано касание.

Как мне достичь этой цели?

Спасибо.

Ответы [ 14 ]

31 голосов
/ 23 июня 2009

Если вы не хотите создавать подкласс UITableView, используйте таймер с табличным представлением didSelectRowAtIndex:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    //checking for double taps here
    if(tapCount == 1 && tapTimer != nil && tappedRow == indexPath.row){
        //double tap - Put your double tap code here
        [tapTimer invalidate];
        [self setTapTimer:nil];

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Double Tap" message:@"You double-tapped the row" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
        [alert show];
        [alert release];
    }
    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;
        [self setTapTimer:[NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(tapTimerFired:) userInfo:nil repeats:NO]];
    }
    else if(tappedRow != indexPath.row){
        //tap on new row
        tapCount = 0;
        if(tapTimer != nil){
            [tapTimer invalidate];
            [self setTapTimer:nil];
        }
    }
}

- (void)tapTimerFired:(NSTimer *)aTimer{
    //timer fired, there was a single tap on indexPath.row = tappedRow
    if(tapTimer != nil){
        tapCount = 0;
        tappedRow = -1;
    }
}

НТН

27 голосов
/ 23 июня 2009

Переопределите в вашем UITableView классе этот метод

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
 {

     if(((UITouch *)[touches anyObject]).tapCount == 2)
    {
    NSLog(@"DOUBLE TOUCH");
    }
    [super touchesEnded:touches withEvent:event];
}
10 голосов
/ 22 июля 2010

В вашем подклассе UITableView сделайте что-то вроде этого:

- (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];
}
9 голосов
/ 12 сентября 2011

Первое определение:

int tapCount;
NSIndexPath *tableSelection;

в качестве переменных уровня класса в файле .h и выполните все необходимые настройки. Тогда ...

- (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;
}
6 голосов
/ 23 января 2013

Я решил реализовать это, переопределив UITableViewCell.

MyTableViewCell.h

@interface MyTableViewCell : UITableViewCell

@property (nonatomic, assign) int numberOfClicks;

@end

MyTableViewCell.m

@implementation MyTableViewCell

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
   UITouch *aTouch = [touches anyObject];
   self.numberOfClicks = [aTouch tapCount];
   [super touchesEnded:touches withEvent:event];
}

TableViewController.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

   MyTableViewCell *myCell = (MyTableViewCell*) [self.tableView cellForRowAtIndexPath:indexPath];

   NSLog(@"clicks:%d", myCell.numberOfClicks);

   if (myCell.numberOfClicks == 2) {
       NSLog(@"Double clicked");
   }
}
6 голосов
/ 04 мая 2011
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]; 
}

Используйте executeSelector для вызова селектора вместо использования таймера. Это решает проблему, упомянутую @ V1ru8.

2 голосов
/ 18 сентября 2014

Другой ответ

int touches;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  touches++;

    if(touches==2){
       //your action
    }
}

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    touches=0;
}
1 голос
/ 20 января 2017

Свифт 3 решения из сравнения ответов. Не нужно никаких расширений, просто добавьте этот код.

override func viewDidLoad() {
    viewDidLoad()

    let doubleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap(sender:)))
    doubleTapGestureRecognizer.numberOfTapsRequired = 2
    tableView.addGestureRecognizer(doubleTapGestureRecognizer)

    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(sender:)))
    tapGestureRecognizer.numberOfTapsRequired = 1
    tapGestureRecognizer.require(toFail: doubleTapGestureRecognizer)
    tableView.addGestureRecognizer(tapGestureRecognizer)
}

func handleTapGesture(sender: UITapGestureRecognizer) {
    let touchPoint = sender.location(in: tableView)
    if let indexPath = tableView.indexPathForRow(at: touchPoint) {
        print(indexPath)
    }
}

func handleDoubleTap(sender: UITapGestureRecognizer) {
    let touchPoint = sender.location(in: tableView)
    if let indexPath = tableView.indexPathForRow(at: touchPoint) {
        print(indexPath)
    }
}
1 голос
/ 14 июня 2015

Согласно @lostInTransit я подготовил код в 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;
    }
}
1 голос
/ 23 июня 2009

Возможно, вам понадобится создать подкласс UITableView и переопределить все подходящие события касания (touchesBegan:withEvent ;, touchesEnded:withEvent и т. Д.). Проверьте события, чтобы увидеть, сколько было касаний, и выполните собственное поведение. Не забудьте вызвать UITableView's сенсорные методы, иначе вы не получите поведение по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...