识别长按和平移手势识别器

我有一个视图,我已经添加了泛和长按UIGestureRecognizer。 锅是用来移动视图。 我想要做的是还要注意触摸已经停止移动(同时保持活动状态)并触发长按。

我发现,长期开始之后永远不会触发长时间的压力。 我试着设置一个委托并执行:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { NSLog(@"simultaneous %@", gestureRecognizer.class); return YES; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { NSLog(@"require fail %@", gestureRecognizer.class); return [gestureRecognizer isKindOfClass:[UIPanGestureRecognizer self]]; // also tried return YES; // also tried return [gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer self]]; } 

我已经尝试了与泛GR的允许移动愚弄,也无济于事。 我正准备放弃在pan gr中使用计时器,然后重新启动,但是我希望SDK能为我做状态机的工作。

如果有人需要它,这里是适合我的代码。 我们的目标是要有一个对长按和平移敏感的视图,包括前面没有平移的长按,反之亦然。

 // setup @property (strong,nonatomic) NSTimer *timer; // triggers the long press during pan @property (strong,nonatomic) UIView *longPressView; // need this to track long press state // view is the view we're interested in panning and long pressing UIPanGestureRecognizer *panGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGR:)]; [view addGestureRecognizer:panGR]; // this starts a long press when no pan has occurred UILongPressGestureRecognizer *longGR = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGR:)]; [view addGestureRecognizer:longGR]; 

当平底锅开始或更改时,启动一个计时器。 如果定时器在平底锅结束之前到期(触摸释放),那么我们有一个长按。

 - (void)panGR:(UIPanGestureRecognizer *)gr { if (gr.state == UIGestureRecognizerStateBegan) { [self startTimer:gr.view]; } else if (gr.state == UIGestureRecognizerStateChanged) { [self startTimer:gr.view]; // do whatever you want to do with pan state in this method // in my case, I'm translating the view here } else if (gr.state == UIGestureRecognizerStateEnded) { if (self.longPressView) { [self longPressEnded]; } else { [self.timer invalidate]; } } } 

我们给定视图的定时器用户信息。 您可能需要存储手势状态的其他部分,如位置等。使用用户信息字典以同样的方式进行操作。

 - (void)startTimer:(UIView *)view { if (self.longPressView) return; [self.timer invalidate]; self.timer = [NSTimer scheduledTimerWithTimeInterval:0.8 target:self selector:@selector(longPressTimer:) userInfo:@{ @"view": view} repeats:NO]; } -(void)longPressTimer:(NSTimer *)timer { self.longPressView = timer.userInfo[@"view"]; [self longPressBegan]; } 

由于定时器方法没有关联的gr,因此将我们通常放在gr处理程序中的所有逻辑分解出来,以便可以由定时器处理程序和gr处理程序调用它们。

 - (void)longPressGR:(UILongPressGestureRecognizer *)gr { if (gr.state == UIGestureRecognizerStateBegan) { self.longPressView = gr.view; [self longPressBegan]; } else if (gr.state == UIGestureRecognizerStateEnded) { [self longPressEnded]; } } - (void)longPressBegan { NSLog(@"long press began"); } - (void)longPressEnded { self.longPressView = nil; NSLog(@"long press ended"); }