Объединение UILongPressGestureRecognizer с UIPanGestureRecognizer - PullRequest
19 голосов
/ 16 августа 2010

Я бы хотел объединить UILongPressGestureRecognizer с UIPanGestureRecognizer.

UIPanGestureRecognizer должен запускаться с долгого нажатия.Есть ли простой способ сделать это?или мне действительно нужно написать свой собственный распознаватель жестов?

Я не хочу что-то похожее на домашнем экране.Вы нажимаете на значок, и через некоторое время значки начинают колебаться.После этого, не отпуская палец от экрана, я могу начать перетаскивать значок под своим пальцем.

Ответы [ 5 ]

21 голосов
/ 27 августа 2010

на самом деле, вам не нужно комбинировать распознаватели жестов - вы можете сделать это исключительно с UILongPressGestureRecognizer ... Вы вводите StateBegan, как только ваши касания остаются в пределах «allowableMovement» для «minimalPressDuration».Вы остаетесь в своем непрерывном longPressGesture до тех пор, пока не поднимаете пальцы - так что вы можете начать двигать пальцами и отслеживать движение с помощью StateChanged.

Жесты длинного нажатия являются непрерывными.Жест начинается (UIGestureRecognizerStateBegan), когда количество допустимых пальцев (numberOfTouchesRequired) было нажато в течение указанного периода (минимальная длительность) и касания не выходят за пределы допустимого диапазона движения (allowableMovement).Распознаватель жестов переходит в состояние «Изменение» при каждом перемещении пальца и заканчивается (UIGestureRecognizerStateEnded) при поднятии любого из пальцев.

18 голосов
/ 17 октября 2013

У меня было немного трудное время для этой проблемы. Принятого ответа было недостаточно. Независимо от того, что я добавлю в этот метод, будут вызываться обработчики панорамирования или longpress. Решение, которое я нашел, было следующим:

  1. Убедитесь, что делегаты распознавателей жестов назначены одному и тому же классу (в моем случае self), и убедитесь, что класс делегата равен 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. Установите BOOL на NO в вашем init или 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. И, наконец, сбросить BOOL в panHandler:

    else if(sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed || sender.state == UIGestureRecognizerStateCancelled) {
        shouldAllowPan = NO;
    }
    
  8. А потом иди, возьми пиво, чтобы поздравить себя. ;)

16 голосов
/ 16 августа 2010

Я нашел решение: Этот метод UIGestureRecognizerDelegate делает именно то, что я искал:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
8 голосов
/ 04 мая 2015

подход Энди Б. в Swift,

  1. Добавление делегата UIGestureRecognizerDelegate в класс

    class ViewController: UIViewController, UIGestureRecognizerDelegate
    
  2. Добавитьпеременная-член

    var shouldAllowPan: Bool = false
    
  3. Добавьте жесты и необходимо добавить делегат жестов панорамирования в VC.Это необходимо, чтобы отключить функции shouldRecognizeSimralleluallyWithGestureRecognizer и жестRecognizerShouldBegin

    // 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 голосов
/ 12 января 2016

Прочитайте раздел «Примечания по подклассам» в справочнике по классу Apple UIGestureRecognizer по адресу:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...