做longPress时启用UIPanGestureRecognizer

我想在UIPanGestureRecognizer执行customView时在customView上启用UIPanGestureRecognizer
(我希望当你customViewcustomView将切换到“移动模式”,你可以通过拖动移动customView 。)

但是在这段代码中,只有longPressAction:调用。 panAction:panAction:
如何修复它以启用PanAction:

 - (void)viewDidLoad { [self.view addSubview:customView]; UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)]; [customView addGestureRecognizer:longPressRecognizer]; UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)]; [customView addGestureRecognizer:panRecognizer]; } - (void)longPressAction:(UILongPressGestureRecognizer *)recognizer { if ([recognizer state] == UIGestureRecognizerStateBegan) { CustomView *customView = (CustomView *)recognizer.view; customView.panRecongnizerEnabled = YES; //panRecongnizerEnabled is CustomView's property } if ([recognizer state] == UIGestureRecognizerStateEnded) { CustomView *customView = (CustomView *)recognizer.view; customView.panRecongnizerEnabled = NO; } } - (void)panAction:(UIPanGestureRecognizer *)recognizer { CustomView *customView = (CustomView *)recognizer.view; if (customCell.panRecongnizerEnabled == NO) return; NSLog(@"running panAction"); } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; } 

您的ViewController需要符合UIGestureRecognizerDelegate 。 我怀疑你或者已经这样做过,否则shouldRecognizeSimultaneouslyWithGestureRecognizer没有任何意义。 但你肯定缺少的是将gestureRecognizer的委托设置为viewController:

 longPressRecognizer.delegate = self; panRecognizer.delegate = self; 

现在你应该同时接受长按和平移。

注意:我测试时没有任何customView,只是将它们添加到self.view 。 至少在这种情况下,上面的代码按预期工作。

我知道这个问题已经关闭了一段时间,但我最近不得不做类似的事情,并且有一个更清洁的解决方案。 UILongPressGestureRecognizer就是您所需要的。

长按手势是连续的。 当指定时间段(minimumPressDuration)按下允许的手指数(numberOfTouchesRequired)并且触摸不超出允许的移动范围(allowableMovement)时,手势开始(UIGestureRecognizerStateBegan)。 每当手指移动时,手势识别器转换到改变状态,并且当任何手指被抬起时,手势识别器结束(UIGestureRecognizerStateEnded)。

因此,根据您的需要,不需要UIPanGestureRecognizer 。 只需添加UILongPressGestureRecognizer并将其附加到主视图即可。

 - (void)viewDidLoad { [super viewDidLoad]; UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)]; // set this to your desired delay before the pan action will start. longPressRecognizer.minimumPressDuration = 0.5; [self.view addGestureRecognizer:longPressRecognizer]; } 

然后,实现longPressAction方法不仅要查看UIGestureRecognizerStateBeganUIGestureRecognizerStateEnded状态,还要查看UIGestureRecognizerStateChanged状态:

 - (void)longPressAction:(UIGestureRecognizer *)recognizer { if ([recognizer state] == UIGestureRecognizerStateBegan || [recognizer state] == UIGestureRecognizerStateChanged ) { CGPoint touchPoint = [recognizer locationInView:self.view]; [self.viewToMove setCenter: touchPoint]; NSLog(@"running panAction"); } } 

在我的示例中,我只是移动一个虚拟视图来跟踪用户手指的中心,但是您可以将任何逻辑放入UIPanGestureRecognizer的代码中。 只需将它放在if块中,它就可以大大简化代码,而且不需要处理两个手势识别器之间的交互。 当用户只是在屏幕上移动手指时(但没有长按),你的代码也会导致对panAction方法的许多不必要的调用。

您可以通过长按后启用平移来完成此操作。 无论如何你必须保存一个标志才能知道是否调用了longPress。 并且为了在longPress之后启用平移手势,您可以使用平移手势委托,如下所示:

 let previewLongPress = UILongPressGestureRecognizer(target: self, action: #selector(onLongPressed(sender:))) let previewPanGesture = UIPanGestureRecognizer(target: self, action: #selector(onPanGesture(sender:))) previewPanGesture?.delegate = self 

你的代表应该是这样的:

 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return gestureRecognizer == previewPanGesture && otherGestureRecognizer == previewLongPress } 

现在,您可以在长按手势后进行平移手势。

希望它能帮助其他人。