La combinaison d'un UILongPressGestureRecognizer avec un UIPanGestureRecognizer
Question
Je d'aime combiner un UILongPressGestureRecognizer avec un UIPanGestureRecognizer.
Le UIPanGestureRecognizer doit commencer par un appui long. Est-il un moyen simple de le faire? ou dois-je vraiment écrire mon propre geste de reconnaissance?
Je wan't quelque chose comme sur l'écran d'accueil. Vous appuyez sur une icône et après un certain temps les icônes commencer vacillement. Par la suite sans relâcher le doigt sur l'écran, je peux commencer à glisser l'icône sous mon doigt autour.
La solution 3
J'ai trouvé une solution: Cette méthode de UIGestureRecognizerDelegate fait exactement ce que je cherchais:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
Autres conseils
En fait, vous ne devez pas combiner geste de reconnaissance - vous pouvez le faire uniquement avec UILongPressGestureRecognizer ... Vous entrez StateBegan une fois que votre contact (es) sont restés dans les « allowableMovement » pour « minimumPressDuration ». Vous restez dans votre longPressGesture continue aussi longtemps que vous ne soulevez pas l'un de vos doigts -. Afin que vous puissiez commencer à bouger vos doigts et de suivre le mouvement à travers StateChanged
gestes à long presse sont continus. Le geste commence (UIGestureRecognizerStateBegan) lorsque le nombre de doigts admissibles (numberOfTouchesRequired) ont appuyé pendant la période spécifiée (minimumPressDuration) et les touches ne se déplacent pas au-delà de la plage autorisée du mouvement (allowableMovement). Les transitions de reconnaissance de geste à l'état à chaque fois qu'un changement doigt se déplace, et elle se termine (UIGestureRecognizerStateEnded) lorsque l'un des doigts sont levées.
J'ai eu un peu de mal à ce problème. La réponse acceptée ne suffit pas. Peu importe ce que je mets dans cette méthode, les gestionnaires de pan ou Longpress obtiendraient invoqué. Une solution que j'ai trouvé comme suit:
- Vérifiez que les délégués geste Recognizers sont affectés à la même classe (dans mon cas auto) et assurer la classe déléguée est un
UIGestureRecognizerDelegate
. -
Ajoutez la méthode suivante à votre délégué de classe (selon la réponse ci-dessus):
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; }
-
Ajoutez la méthode suivante à votre délégué de classe:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && ! shouldAllowPan) { return NO; } return YES; }
-
Ensuite, ajoutez soit une propriété ou Ivar qui permettra de suivre si la casserole devrait être autorisé à commencer (voir méthode ci-dessus). Dans mon cas
BOOL shouldAllowPan
. -
Set BOOL à
NO
dans votreinit
ouviewDidLoad
. A l'intérieur de votre gestionnaire de Longpress mis BOOL àYES
. Je le fais comme ceci:- (void) longPressHandler: (UILongPressGestureRecognizer *) gesture { if(UIGestureRecognizerStateBegan == gesture.state) { shouldAllowPan = NO; } if(UIGestureRecognizerStateChanged == gesture.state) { shouldAllowPan = YES; } }
-
A l'intérieur du Panhandler je fais un contrôle sur le BOOL:
- (void)panHandler:(UIPanGestureRecognizer *)sender{ if(shouldAllowPan) { // do your stuff }
-
Et enfin réinitialiser le BOOL dans le Panhandler:
else if(sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed || sender.state == UIGestureRecognizerStateCancelled) { shouldAllowPan = NO; }
-
Et puis aller prendre une bière pour vous féliciter. ;)
L'approche de Andy B à Swift,
-
Ajoutez UIGestureRecognizerDelegate délégué à la classe
class ViewController: UIViewController, UIGestureRecognizerDelegate
-
Ajouter une variable membre
var shouldAllowPan: Bool = false
-
Ajoutez les gestes et la nécessité d'ajouter le délégué pan geste à la VC. Cela est nécessaire pour tirer au large des fonctions shouldRecognizeSimultaneouslyWithGestureRecognizer et 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)
-
Autoriser gestes simultanés
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; }
-
A l'intérieur du temps gestionnaire de presse:
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 } }
Lisez la section "Notes sous-classement" de UIGestureRecognizer Référence de la classe d'Apple à l'adresse: