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

相關問題