ジェスチャー方法(パンジェスチャーとスワイプジェスチャー)の間に優先条件はありますか?

StackOverflow https://stackoverflow.com/questions/4875255

質問

パンジェスチャーとスワイプジェスチャーを使用したアプリケーションを開発しています。そのため、スワイプジェスチャーを行うたびに、パンジェスチャーのメソッドは常に呼び出され、スワイプジェスチャー方法は呼び出されません。

すべてのジェスチャー方法の間に優先順位はありますか?

役に立ちましたか?

解決

次の方法を実装することにより、それらを並行して呼び出すことができます UIGestureRecognizerDelegate プロトコル:

- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer 
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UISwipeGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

他のヒント

にプロパティがあります UIGestureRecognizer デフォルトである「cancelstouchesinview」と呼ばれるクラス YES. 。これにより、保留中のジェスチャーがキャンセルされます。パンジェスチャーは、「タッチアップ」イベントが必要ではないため、最初に認識されているため、スワイプジェスチャーがキャンセルされます。

両方のジェスチャーを認識したい場合は、次を追加してみてください。

[yourPanGestureInstance setCancelsTouchesInView:NO];

スワイプを優先します

優先順位を与えることができます UIGestureRecognizer とともに require(toFail:) 方法。

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

myPanGesture.require(toFail: mySwipeGestureRecognizer)

今あなた あなたの場合にのみ実行されます スワイプ 失敗します。


使用する 全てにおいて

場合 スワイプ ジェスチャー認識者はこのセットアップでうまく再生されません、あなたはあなたのすべてのロジックを より多くの制御のためのジェスチャー認識者。

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
    }
}

上記のコードのデモは次のとおりです。

enter image description here

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top