Есть ли какое-либо условие приоритета между методами жестов (жест панорамирования и жест смахивания)?

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

Есть ли приоритет между всеми методами жестов?




Ответы (3)


Вы можете вызывать их параллельно, реализуя следующий метод протокола UIGestureRecognizerDelegate:

- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer 
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UISwipeGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}
person Atanas Chanev    schedule 14.04.2012
comment
Я использую github.com/XavierDK/XDKAirMenu, а также использую жест смахивания в одном из моих контроллеров. так что этот делегат не работает для меня - person iAnkit; 10.02.2015

В классе UIGestureRecognizer есть свойство, называемое «cancelsTouchesInView», которое по умолчанию равно YES. Это приведет к отмене любых ожидающих жестов. Первым распознается жест панорамирования, поскольку для него не требуется событие «подправить», поэтому он отменяет жест смахивания.

Если вы хотите, чтобы оба жеста распознавались, попробуйте добавить:

[yourPanGestureInstance setCancelsTouchesInView:NO];

person picciano    schedule 02.02.2011
comment
спасибо за ответ, но этот метод все еще не идентифицирует жест смахивания - person NIKHIL; 03.02.2011
comment
Я также попробовал метод shouldRecognizeSimultaneousWithGestureRecognizer в файле UIGestureRecognizer.H. - person NIKHIL; 03.02.2011

Отдавать приоритет смахиванию

Вы можете отдать приоритет UIGestureRecognizer с помощью метода require(toFail:).

@IBOutlet var myPanGestureRecognizer: UIPanGestureRecognizer!
@IBOutlet var mySwipeGestureRecognizer: UISwipeGestureRecognizer!

myPanGesture.require(toFail: mySwipeGestureRecognizer)

Теперь ваше панорамирование будет выполняться, только если ваш прокрутка не сработает.


Используйте pan для всего

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

let minHeight: CGFloat = 100
let maxHeight: CGFloat = 700
let swipeVelocity: CGFloat = 500
var previousTranslationY: CGFloat = 0

@IBOutlet weak var cardHeightConstraint: NSLayoutConstraint!

@IBAction func didPanOnCard(_ sender: Any) {

    guard let panGesture = sender as? UIPanGestureRecognizer else { return }

    let gestureEnded = bool(panGesture.state == UIGestureRecognizerState.ended)
    let velocity = panGesture.velocity(in: self.view)

    if gestureEnded && abs(velocity.y) > swipeVelocity {
        handlePanOnCardAsSwipe(withVelocity: velocity.y)
    } else {
        handlePanOnCard(panGesture)
    }
} 

func handlePanOnCard(_ panGesture: UIPanGestureRecognizer) {

    let translation = panGesture.translation(in: self.view)
    let translationYDelta = translation.y - previousTranslationY

    if abs(translationYDelta) < 1 { return } // ignore small changes

    let newCardHeight = cardHeightConstraint.constant - translationYDelta

    if newCardHeight > minHeight && newCardHeight < maxHeight {
        cardHeightConstraint.constant = newCardHeight
        previousTranslationY = translation.y
    }

    if panGesture.state == UIGestureRecognizerState.ended {
        previousTranslationY = 0
    }
}

func handlePanOnCardAsSwipe(withVelocity velocity: CGFloat) {
    if velocity.y > 0 {
        dismissCard() // implementation not shown
    } else {
        maximizeCard() // implementation not shown
    }
}

Вот демонстрация приведенного выше кода в действии.

введите здесь описание изображения

person Derek Soike    schedule 13.01.2018