长按后如何取消触摸?

How do I cancel touches after long press?

我有一个显示自定义视图单元格的表格视图。在 viewWillAppear 中,我在 UITableView 上设置了一个长按手势识别器。我的长按正在触发并显示有关长期按下的单元格的信息。但是,当我松开按键时,didSelectRowAtIndexPath 方法正在触发。有没有办法在长按触发后取消触摸,这样 select 行就不会被触发?

我已经看到 并且这个问题似乎没有关于如何解决问题的充分答案。

@implementation ViewController
UILongPressGestureRecognizer *lpgr;
.
.
.

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    // setup long press

    lpgr = [[UILongPressGestureRecognizer alloc]
                                          initWithTarget:self action:@selector(handleLongPress:)];
    lpgr.minimumPressDuration = 0.5; //seconds
    lpgr.delegate = self;
    lpgr.cancelsTouchesInView = true;
    [self.myTableview addGestureRecognizer:lpgr];
    [self.myTableview.panGestureRecognizer requireGestureRecognizerToFail:lpgr]; ...
.
.
.

-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{

    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {

        CGPoint p = [gestureRecognizer locationInView:self.myTableview];

        NSIndexPath *indexPath = [self.myTableview indexPathForRowAtPoint:p];
        if (indexPath == nil) {
            NSLog(@"long press on table view but not on a row");
        } else {
            UITableViewCell *cell = [self.myTableview cellForRowAtIndexPath:indexPath];
            CensusData *currentUser;
            if(self.isFiltered){
                currentUser = (CensusData*)[self.filteredTableData objectAtIndex:indexPath.row];
            }else{
                currentUser = (CensusData*)[self.dataArray objectAtIndex:indexPath.row];
            }
            NSLog(@"CURRENT ROW WITH LONG PRESS: %@", currentUser.friendlyName);

        }
    }
}
.
.
.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

当手势处于活动状态(开始但未结束)时,禁用 table 视图上的选择...

- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
    if (gr.state == UIGestureRecognizerStateBegan) {
        self.myTableview.allowsSelection = NO;
    } else if (gr.state == UIGestureRecognizerStateEnded) {
        self.myTableview.allowsSelection = YES;
    }
}

无需设置委托、设置 cancelsTouches 或实施 shouldRecognize...(除非您需要这些用于其他目的)。

编辑 这个vc 是一个最低限度的完整测试。它需要一个带有连接到插座的 table 视图和 vc 作为数据源和委托的故事板...

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@property(weak,nonatomic) IBOutlet UITableView *tableView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UILongPressGestureRecognizer *gr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
    [self.tableView addGestureRecognizer:gr];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 50;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    cell.textLabel.text = [NSString stringWithFormat:@"Row %ld", indexPath.row];
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"selected %@", indexPath);
}

- (void)handleLongPress:(UILongPressGestureRecognizer *)gr {
    if (gr.state == UIGestureRecognizerStateBegan) {
        NSLog(@"long press began");
        self.tableView.allowsSelection = NO;
    } else if (gr.state == UIGestureRecognizerStateEnded) {
        NSLog(@"long press ended");
        self.tableView.allowsSelection = YES;
    }
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

您可以禁用 tableview,然后只有 longGesture 可以正常工作

UILongPressGestureRecognizer* longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPress:)];
[self.myTableview addGestureRecognizer:longPressRecognizer];



-(void)onLongPress:(UILongPressGestureRecognizer*)pGesture
{

    if (pGesture.state == UIGestureRecognizerStateRecognized)
    {
        //Do something to tell the user!
    }
    if (pGesture.state == UIGestureRecognizerStateEnded)
    {
        CGPoint p = [pGesture locationInView:self.myTableview];

        NSIndexPath *indexPath = [self.myTableview indexPathForRowAtPoint:p];

    }

}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
   if ([touch.view isDescendantOfView:self.myTableview]) {

      // Don't let selections of auto-complete entries fire the
      // gesture recognizer
      return NO;
   }

   return YES;

}