164

我正在尝试将 2UITapGestureRecognizers个添加到视图中,一个用于单击,一个用于双击事件。单击识别器按预期工作(单独)。但我似乎无法让双击识别器工作。

已尝试尝试使用 : 之类的属性,cancelsTouchesInView但仍然无法正常工作。delaysTouchesBegandelaysTouchesEnded

当我双击时,单击识别器将始终被激活,并且双击事件也将被发送到超级视图。但是自定义双击识别器似乎根本没有收到通知。

文档似乎表明上述 3 个属性可用于此目的。但我只是不确定应该设置哪些值以及在哪个识别器上(单、双或两者)。希望熟悉这方面的人可以提供帮助。

以下是最新更新的代码块。

// ****** gesture recognizers ******

- (void)addSingleAndDoubleTapGestureRecognizersToView:(UIView *)view
{
    // single tap    
    UITapGestureRecognizer *singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: tableViewController action: @selector(handleSingleTapOnView:)];                                 
    [singleTapRecognizer setNumberOfTouchesRequired:1];
    [view addGestureRecognizer: singleTapRecognizer];

    // double tap 
    UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget: tableViewController action: @selector (handleDoubleTapOnView:)];        
    [doubleTapRecognizer setNumberOfTouchesRequired:2];         
    [singleTapRecognizer requireGestureRecognizerToFail: doubleTapRecognizer];
    [view addGestureRecognizer: doubleTapRecognizer];         
}

- (void)handleSingleTapOnView:(id)sender
{

}

- (void)handleDoubleTapOnView:(id)sender
{

}
4

9 回答 9

444
UITapGestureRecognizer *singleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSingleTap)] autorelease];
singleTap.numberOfTapsRequired = 1; 
[self.view addGestureRecognizer:singleTap];

UITapGestureRecognizer *doubleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doDoubleTap)] autorelease];
doubleTap.numberOfTapsRequired = 2; 
[self.view addGestureRecognizer:doubleTap];

[singleTap requireGestureRecognizerToFail:doubleTap];

注意: 如果你正在使用 numberOfTouchesRequired 它必须是 .numberOfTouchesRequired = 1;

对于斯威夫特

let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(didPressPartButton))
singleTapGesture.numberOfTapsRequired = 1
view.addGestureRecognizer(singleTapGesture)

let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(didDoubleTap))
doubleTapGesture.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTapGesture)

singleTapGesture.require(toFail: doubleTapGesture)
于 2012-01-16T06:04:32.723 回答
51

斯威夫特 3 解决方案:

let singleTap = UITapGestureRecognizer(target: self, action:#selector(self.singleTapAction(_:)))
singleTap.numberOfTapsRequired = 1
view.addGestureRecognizer(singleTap)

let doubleTap = UITapGestureRecognizer(target: self, action:#selector(self.doubleTapAction(_:)))
doubleTap.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTap)

singleTap.require(toFail: doubleTap)

在代码行singleTap.require(toFail: doubleTap)我们强制单击等待并确保单击事件不是双击。

于 2016-10-27T13:13:44.067 回答
32

您需要使用 requireGestureRecognizerToFail: 方法。像这样的东西:

[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];

于 2012-01-16T05:57:50.517 回答
15

//----首先你必须分配双击和单击手势-------//

UITapGestureRecognizer* doubleTap = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleDoubleTap:)];

UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget : self action : @selector (handleSingleTap:)];

[singleTap requireGestureRecognizerToFail : doubleTap];
[doubleTap setDelaysTouchesBegan : YES];
[singleTap setDelaysTouchesBegan : YES];

//------------------------------------点击次数----------------//

[doubleTap setNumberOfTapsRequired : 2];
[singleTap setNumberOfTapsRequired : 1];

//------- 在视图或按钮上添加双击和单击手势--------//

[self.view addGestureRecognizer : doubleTap];
[self.view addGestureRecognizer : singleTap];
于 2012-07-26T12:56:38.077 回答
10

不确定这是否正是您要找的,但我在没有手势识别器的情况下进行了单击/双击。我在 UITableView 中使用它,所以我在 didSelectRowAtIndexPath 方法中使用了该代码

    tapCount++;
    switch (tapCount)
    {
        case 1: //single tap
            [self performSelector:@selector(singleTap:) withObject: indexPath afterDelay: 0.2];
            break;
        case 2: //double tap
            [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(singleTap:) object:indexPath];
            [self performSelector:@selector(doubleTap:) withObject: indexPath];
            break;
        default:
            break;
    }
    if (tapCount>2) tapCount=0;

使用 NSIndexPath 作为参数的方法 singleTap 和 doubleTap 是无效的:

- (void)singleTap:(NSIndexPath *)indexPath {
  //do your stuff for a single tap
}

- (void)doubleTap:(NSIndexPath *)indexPath {
  //do your stuff for a double tap
}

希望能帮助到你

于 2012-01-17T09:26:04.610 回答
3

Swift 2 的解决方案:

let singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleSingleTap))
singleTapGesture.numberOfTapsRequired = 1 // Optional for single tap
view.addGestureRecognizer(singleTapGesture)

let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
doubleTapGesture.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTapGesture)

singleTapGesture.requireGestureRecognizerToFail(doubleTapGesture)
于 2016-07-11T14:59:17.110 回答
1

我实现了 UIGestureRecognizerDelegate 方法来检测 singleTap 和 doubleTap。

就这样做吧。

 UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleDoubleTapGesture:)];
    [doubleTap setDelegate:self];
    doubleTap.numberOfTapsRequired = 2;
    [self.headerView addGestureRecognizer:doubleTap];

    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleSingleTapGesture:)];
    singleTap.numberOfTapsRequired = 1;
    [singleTap setDelegate:self];
    [doubleTap setDelaysTouchesBegan:YES];
    [singleTap setDelaysTouchesBegan:YES];
    [singleTap requireGestureRecognizerToFail:doubleTap];
    [self.headerView addGestureRecognizer:singleTap];

然后实现这些委托方法。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
    return  YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}
于 2017-05-10T13:25:48.003 回答
0

有些视图内置了自己的双击识别器(MKMapView例如)。要解决这个问题,您需要实现UIGestureRecognizerDelegate方法shouldRecognizeSimultaneouslyWithGestureRecognizer并返回YES

首先实现你的双识别器和单识别器:

// setup gesture recognizers
UITapGestureRecognizer* singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                action:@selector(mapViewTapped:)];
singleTapRecognizer.delegate = self;
singleTapRecognizer.numberOfTapsRequired = 1;


UITapGestureRecognizer* doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                      action:@selector(mapViewDoubleTapped:)];
doubleTapRecognizer.delegate = self;    // this allows
doubleTapRecognizer.numberOfTapsRequired = 2;
[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];

然后实现:

#pragma mark UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer
*)otherGestureRecognizer {  return YES; }
于 2014-01-07T02:22:24.840 回答
-1

参考@stanley 的评论 -

不要尝试使用点击手势来进行行选择,UITableView因为它已经具有完整的点击处理......

但是您必须在单击手势识别器上将“取消视图中的触摸”设置为“否”,否则它将永远不会获得点击事件。

于 2014-07-09T15:57:54.457 回答