Manipulation des reconnaisseurs de gestes dans iOS6

Apparemment iOS 6 essaie de gérer automatiquement la situation quand vous avez un reconnaissance de geste et un UIButton au même endroit, étant activé pour le même geste.

Cette nouvelle gestion automatique résout le problème lorsque vous souhaitez cliquer sur le button au lieu d'activer le module de reconnaissance des gestes, mais crée un nouveau problème lorsque vous voulez que le module de reconnaissance des gestes fonctionne.

Dans iOS 5, vous pouvez implémenter:

 -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 

pour transférer l'action à l' UIButton cas de conflit.

Cela ne semble pas fonctionner dans iOS 6. En outre, l'inversion du comportement de cette méthode (car maintenant UIButton a la priorité au lieu de la reconnaissance de geste) ne fonctionnera pas.


Méthode complète:

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if ([touch.view isKindOfClass:[UIControl class]]){ return NO; } return YES; } 

Je l'ai fait pour contourner le problème, le changer comme bon vous semble:

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { [self MyCommonSelector];// this will work for ios 5 return Yes; } 

Ajoutez la cible dans le button où vous déclarez que cela appellera dans iOS 6:

 [self.myButton addTarget:self action:@selector(MyCommonSelector) forControlEvents:UIControlEventTouchUpInside]; 

Faites vos trucs dans cette méthode qui sera également appelée sur le button et appuyez sur le geste que vous devez appeler:

 -(void)MyCommonSelector { //Do your stuff here what you want to do with Gesture too. } 

Bien que je ne sais pas pourquoi vous metsortingez UIButtons là si vous ne voulez pas qu'ils soient tapés, vous pouvez empêcher les sous-vues de recevoir des touches en -hitTest:withEvent: la -hitTest:withEvent: de votre vue contenant.

-hitTest:withEvent: returnne par défaut le "descendant le plus éloigné du récepteur dans la hiérarchie de vue (y compris elle-même) qui contient un point spécifié" , donc par défaut, lorsque vous tapotez sur l'un des buttons, votre vue contiendra le button.

Votre implémentation devrait ressembler à ceci:

 - (UIView *)hitTest:(CGPoint)aPoint withEvent:(UIEvent *)event { if ([self pointInside:aPoint]) { return self; } else { return nil; } } 

Donc, si la vue de votre conteneur sur laquelle il est appelé contient le sharepoint contact, il returnne lui-même et le détecteur de mouvement attaché à celui-ci aura le toucher.

Étant donné que cette implémentation ne renvoie jamais de sous-vue, aucun des UIButtons n'aura l'occasion de répondre aux touches.

Je sais que cela semble simplist, mais avez-vous envisagé de définir la propriété userInteractionEnabled de UIButton sur "NO"? Cela devrait l'enlever automatiquement du système d'essai de coup et de reconnaissance de geste.