How can I detect a double tap on a certain cell in UITableView?

后端 未结 14 1023
悲哀的现实
悲哀的现实 2020-12-01 00:18

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

相关标签:
14条回答
  • 2020-12-01 00:48

    Swift 3 solution from compare answers. No need any extensions, just add this code.

    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)
        }
    }
    
    0 讨论(0)
  • 2020-12-01 00:49

    Another answer

    int touches;
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
      touches++;
    
        if(touches==2){
           //your action
        }
    }
    
    - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        touches=0;
    }
    
    0 讨论(0)
  • 2020-12-01 00:50

    I chose to implement it by overriding the 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");
       }
    }
    
    0 讨论(0)
  • 2020-12-01 00:51

    You'll probably need to subclass UITableView and override whatever touch events are appropriate (touchesBegan:withEvent;, touchesEnded:withEvent, etc.) Inspect the events to see how many touches there were, and do your custom behavior. Don't forget to call through to UITableView's touch methods, or else you won't get the default behavior.

    0 讨论(0)
  • 2020-12-01 00:56

    Note: please see the comments below to see though while this solution worked for me, it still may not be a good idea.

    An alternative to creating a subclass of UITableView or UITableViewCell (and to using a timer) would be just to extend the UITableViewCell class with a category, for example (using @oxigen's answer, in this case for the cell instead of the table):

    @implementation UITableViewCell (DoubleTap)
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        if(((UITouch *)[touches anyObject]).tapCount == 2)
        {
            NSLog(@"DOUBLE TOUCH");
        }
        [super touchesEnded:touches withEvent:event];
    }
    @end
    

    This way you don't have to go around renaming existing instances of UITableViewCell with the new class name (will extend all instances of the class).

    Note that now super in this case (this being a category) doesn't refer to UITableView but to its super, UITView. But the actual method call to touchesEnded:withEvent: is in UIResponder (of which both UITView and UITableViewCell are subclasses), so there's no difference there.

    0 讨论(0)
  • 2020-12-01 00:57

    Here's my complete solution:

    CustomTableView.h

    //
    //  CustomTableView.h
    //
    
    #import <UIKit/UIKit.h>
    
    @interface CustomTableView : UITableView
    
        // Nothing needed here
    
    @end
    

    CustomTableView.m

    //
    //  CustomTableView.m
    //
    
    #import "CustomTableView.h"
    
    @implementation CustomTableView
    
    
    //
    // Touch event ended
    //
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
    
        // For each event received
        for (UITouch * touch in touches) {
    
            NSIndexPath * indexPath = [self indexPathForRowAtPoint: [touch locationInView:self] ];
    
            // One tap happened
            if([touch tapCount] == 1)
            {
                // Call the single tap method after a delay
                [self performSelector: @selector(singleTapReceived:)
                           withObject: indexPath
                           afterDelay: 0.3];
            }
    
    
            // Two taps happened
            else if ([touch tapCount] == 2)
            {
                // Cancel the delayed call to the single tap method
                [NSObject cancelPreviousPerformRequestsWithTarget: self
                                                         selector: @selector(singleTapReceived:)
                                                           object: indexPath ];
    
                // Call the double tap method instead
                [self performSelector: @selector(doubleTapReceived:)
                           withObject: indexPath ];
            }
    
    
        }
    
        // Pass the event to super
        [super touchesEnded: touches
                  withEvent: event];
    
    }
    
    
    //
    // Single Tap
    //
    -(void) singleTapReceived:(NSIndexPath *) indexPath
    {
        NSLog(@"singleTapReceived - row: %ld",(long)indexPath.row);
    }
    
    
    //
    // Double Tap
    //
    -(void) doubleTapReceived:(NSIndexPath *) indexPath
    {
        NSLog(@"doubleTapReceived - row: %ld",(long)indexPath.row);
    }
    
    
    
    @end
    
    0 讨论(0)
提交回复
热议问题