将UILongPressGestureRecognizer与UIPanGestureRecognizer组合

问题描述 投票:19回答:6

我想将UILongPressGestureRecognizer与UIPanGestureRecognizer结合使用。

UIPanGestureRecognizer应该从长按开始。有没有简单的方法可以做到这一点?还是我真的必须编写自己的手势识别器?

我不会在主屏幕上显示类似的内容。您按一个图标,一段时间后,图标开始摆动。之后,无需从屏幕上松开手指,我就可以开始在手指下面拖动图标。

objective-c cocoa-touch uigesturerecognizer uipangesturerecognizer uilongpressgesturerecogni
6个回答
24
投票

实际上,您不必结合使用手势识别器-您可以仅使用UILongPressGestureRecognizer来完成此操作……只要您的触摸停留在'allowableMovement'中,并且输入'minimumPressDuration',就可以输入StateBegan。只要您不抬起任何手指,就可以保持连续的longPressGesture状态-这样就可以开始移动手指并通过StateChanged跟踪移动。

长按手势是连续的。当在指定的时间段内(minimumPressDuration)按下了允许的手指数(numberOfTouchesRequired),并且触摸未超出允许的移动范围(allowableMovement)时,手势开始(UIGestureRecognizerStateBegan)。每当手指移动时,手势识别器都会转换为“更改”状态,并且在任何手指抬起时手势识别器都会终止(UIGestureRecognizerStateEnded)。


19
投票

我在解决这个问题上有些困难。接受的答案还不够。无论我在该方法中使用什么方法,都会调用pan或longpress处理程序。我发现的解决方案如下:

  1. 确保手势识别器的委托人被分配到同一类(在我的情况下为自我),并确保委托人类别为UIGestureRecognizerDelegate
  2. 将以下委托方法添加到您的类中(按照上面的答案):

    - (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
    shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 
         return YES;
    }
    
  3. 将以下委托方法添加到您的类中:

    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
         if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && ! shouldAllowPan) {
              return NO;
         }
         return YES;
    }
    
  4. 然后添加一个属性或ivar,它将跟踪是否应允许平移开始(请参见上面的方法)。就我而言BOOL shouldAllowPan

  5. NOinit中将BOOL设置为viewDidLoad。在longPress处理程序内部,将BOOL设置为YES。我是这样的:

    - (void) longPressHandler: (UILongPressGestureRecognizer *) gesture {
    
         if(UIGestureRecognizerStateBegan == gesture.state) {
            shouldAllowPan = NO;
         }
    
         if(UIGestureRecognizerStateChanged == gesture.state) {
            shouldAllowPan = YES;
         }
    }
    
  6. 在panHandler里面,我在BOOL上进行了检查:

    - (void)panHandler:(UIPanGestureRecognizer *)sender{
        if(shouldAllowPan) {
              // do your stuff
        }
    
  7. 最后在panHandler中重置BOOL:

    else if(sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed || sender.state == UIGestureRecognizerStateCancelled) {
        shouldAllowPan = NO;
    }
    
  8. 然后去喝啤酒祝贺自己。 ;)


16
投票

我找到了解决方案:这个UIGestureRecognizerDelegate方法完全符合我的期望:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

9
投票

Andy B在Swift中的方法,

  1. UIGestureRecognizerDelegate委托添加到类中

    class ViewController: UIViewController, UIGestureRecognizerDelegate
    
  2. 添加成员变量

    var shouldAllowPan: Bool = false
    
  3. 添加手势,需要将平移手势委托添加到VC。需要此操作来触发shouldRecognizeWithGestureRecognizer和gestureRecognizerShouldBegin函数

    // long press
    let longPressRec = UILongPressGestureRecognizer(target: self, action: "longPress:")
    yourView.addGestureRecognizer(longPressRec)
    
    // drag
    let panRec = UIPanGestureRecognizer(target: self, action: "draggedView:")
    panRec.delegate = self
    yourView.addGestureRecognizer(panRec)
    
  4. 允许同时手势

    func gestureRecognizer(UIGestureRecognizer,
    shouldRecognizeSimultaneouslyWithGestureRecognizer:UIGestureRecognizer) -> Bool {
        // println("shouldRecognizeSimultaneouslyWithGestureRecognizer");
        return true
    }
    
    func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
         // We only allow the (drag) gesture to continue if it is within a long press
         if((gestureRecognizer is UIPanGestureRecognizer) && (shouldAllowPan == false)) {
             return false;
         }
         return true;
    }
    
  5. 在长按处理程序内:

    func longPress(sender: UILongPressGestureRecognizer) {
    
        if(sender.state == .Began) {
            // handle the long press
        }
        else if(sender.state == .Changed){
            shouldAllowPan = true
    
        }
        else if (sender.state == .Ended) {
            shouldAllowPan = false
        }
    } 
    

0
投票

在以下位置阅读Apple的UIGestureRecognizer类参考的“子类注释”部分:

https://developer.apple.com/library/prerelease/tvos/documentation/UIKit/Reference/UIGestureRecognizer_Class/


0
投票

用于组合更多手势:

  1. 创建局部变量var shouldAllowSecondGesture : Bool = false
  2. 创建两个识别器

    让longPressRec = UILongPressGestureRecognizer(目标:自我,动作:#selector(self.startDrag(sender :)))cell.addGestureRecognizer(longPressRec)让panGestureRecognizer = UIPanGestureRecognizer(目标:自我,行动​​:#selector(self.handlePan(sender :)))cell.isUserInteractionEnabled = truecell.addGestureRecognizer(panGestureRecognizer)

  3. 扩展您的VC并实现GestureRecognizerDelegate以实现此方法。

    扩展名YourViewController:UIGestureRecognizerDelegate {

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    
    
    
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
             // We only allow the (drag) gesture to continue if it is within a long press
             if((gestureRecognizer is UIPanGestureRecognizer) && (shouldAllowPan == false)) {
                 return false
             }
             return true
        }
    
    
    @objc func startDrag(sender:UIPanGestureRecognizer) {
    
        if(sender.state == .began) {
                // handle the long press
            }
        else if(sender.state == .changed){
                shouldAllowPan = true
    
            }
            else if (sender.state == .ended) {
                shouldAllowPan = false
            }
        }
    
© www.soinside.com 2019 - 2024. All rights reserved.