17

我想将UILongPressGestureRecognizer与UIPanGestureRecognizer结合使用。将UILongPressGestureRecognizer与UIPanGestureRecognizer结合使用

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

我不喜欢在主屏幕上。你按下一个图标,一段时间后图标开始摆动。之后,不要将手指从屏幕上松开,我可以开始拖动手指周围的图标。

回答

16

我找到了一个解决方案: 这UIGestureRecognizerDelegate方法不正是我寻找:

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

其实,你不必手势识别相结合 - 你可以做到这一点单独与UILongPressGestureRecognizer ......你一旦您的触摸在“minimumPressDuration”的“allowableMovement”内保持不变,请输入StateBegan。只要您不抬起任何手指,您就可以保持持续的长按压 - 所以您可以开始移动手指并通过StateChanged跟踪动作。

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

+3

那里,你可以运行到虽然许多问题。关于UIPanGestureRecognizer的一个最好的事情是,它可以让你平移整个窗口,并仍然返回值,而UILongPressGestureRecognizer不会留下子视图(至少那些与ClipsToBounds) – Kpmurphy91 2013-06-11 05:15:40

+1

此外,当你移动时没有'速度'可用LongPress – 2016-01-05 06:18:44

15

我对这个问题有点困难。接受的答案还不够。无论我用什么方法,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. 在您的initviewDidLoad中将BOOL设置为NO。在您的longPress处理程序中,将BOOL设置为YES。我不喜欢这样写道:

    - (void) longPressHandler: (UILongPressGestureRecognizer *) gesture { 
    
        if(UIGestureRecognizerStateBegan == gesture.state) { 
         shouldAllowPan = NO; 
        } 
    
        if(UIGestureRecognizerStateChanged == gesture.state) { 
         shouldAllowPan = YES; 
        } 
    } 
    
  6. 我做的BOOL检查的乞丐内幕:

    - (void)panHandler:(UIPanGestureRecognizer *)sender{ 
        if(shouldAllowPan) { 
          // do your stuff 
        } 
    
  7. 最后复位乞丐内BOOL:

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

+1

+1。这些步骤真的帮助我解决了操作的目标:只允许长按后拖动。 只需要2条评论: 在步骤5中,检查“开始”然后设置为“是”就足够了。 ''' \t如果(UIGestureRecognizerStateBegan == gesture.state){ \t \t self.shouldAllowDrag = YES; \t} ''' 而在第6步中,不需要检查'shouldAllowPan'。 - 抱歉未格式化的代码。 – 2014-08-08 23:46:05

+1

我实施了Andy的解决方案,它的工作非常棒。为了获得我想要的响应能力,我还改变了最小长按持续时间:UILongPressGestureRecognizer * lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGesture :)]; lpgr.delegate = self; lpgr.minimumPressDuration = 0.05; – chmaynard 2014-11-07 06:17:22

+1

这帮了我很多。谢谢!我将添加一个Swift解决方案,以便它可以帮助其他人。 – duyn9uyen 2015-05-04 14:40:18

5

安迪B的在夫特方法,

  1. UIGestureRecognizerDelegate代表添加到类

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

    var shouldAllowPan: Bool = false 
    
  3. 添加手势并需要将平移手势委托添加到VC。这需要关火shouldRecognizeSimultaneouslyWithGestureRecognizer和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 
        } 
    } 
    
+3

你忘了6。拿起啤酒。 :) :) – 2015-05-05 12:23:42

+1

@ duyn9uyen感谢您将它转换为Swift。 – 2015-11-14 04:07:44

+0

@ duyn9uyen感谢您的转换,并且这个工作就像一个魅力。 – aznelite89 2017-05-19 07:48:41

相关问题