Esiste una condizione prioritaria tra i metodi di gesto (gesto di pan e gesto di scorrimento)?
Domanda
Sto sviluppando un'applicazione in cui ho usato il gesto di Pan e il gesto di scorrimento. Quindi ogni volta che faccio il gesto di scorrimento, ma il metodo del gesto di Pan viene sempre chiamato e il metodo del gesto di scorrimento non viene chiamato.
C'è qualche priorità tra tutto il metodo di gesto?
Soluzione
Puoi chiamarli in parallelo implementando il seguente metodo del UIGestureRecognizerDelegate
protocollo:
- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UISwipeGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Altri suggerimenti
C'è una proprietà sul file UIGestureRecognizer
Classe chiamata "CancelStouchesInview" a cui è default YES
. Ciò causerà l'annullamento dei gesti in sospeso. Il gesto di Pan viene riconosciuto per primo poiché non ha bisogno di avere un evento "ritocco", quindi annulla il gesto di scorrimento.
Se vuoi che entrambi i gesti vengano riconosciuti, prova ad aggiungere:
[yourPanGestureInstance setCancelsTouchesInView:NO];
Dare priorità a scorrere
Puoi dare la priorità a un file UIGestureRecognizer
con il require(toFail:)
metodo.
@IBOutlet var myPanGestureRecognizer: UIPanGestureRecognizer!
@IBOutlet var mySwipeGestureRecognizer: UISwipeGestureRecognizer!
myPanGesture.require(toFail: mySwipeGestureRecognizer)
Adesso tuo padella eseguirà solo se il tuo Swipe non riesce.
Uso padella per tutto
Se la Swipe e padella I riconoscimenti dei gesti non giocano bene con questa configurazione, è possibile lanciare tutta la tua logica nel padella Riconoscimento dei gesti per un maggiore controllo.
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
}
}
Ecco una demo del codice sopra in azione.