82 votes

UIGestureRecognizer bloque la sous-vue pour la gestion des événements tactiles.

J'essaie de comprendre comment cela se fait la bonne façon . J'ai essayé de dépeindre la situation : enter image description here

J'ajoute un UITableView comme une sous-vue d'un UIView . Le site UIView répond à un tapotement et pinchGestureRecognizer Mais en faisant cela, le tableau ne réagit plus à ces deux gestes (il réagit toujours aux balayages).

J'ai réussi à le faire fonctionner avec le code suivant, mais ce n'est évidemment pas une bonne solution et je suis sûr qu'il existe une meilleure solution. Ce code est placé dans le fichier UIView (la vue supérieure) :

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if([super hitTest:point withEvent:event] == self) {
        for (id gesture in self.gestureRecognizers) {
            [gesture setEnabled:YES];
        }
        return self;
    }
    for (id gesture in self.gestureRecognizers) {
        [gesture setEnabled:NO];
    }
    return [self.subviews lastObject];
}

182voto

Justin Points 9636

J'ai eu un problème très similaire et j'ai trouvé ma solution dans cette question SO . En résumé, définissez vous comme le délégué de votre entreprise. UIGestureRecognizer puis vérifiez la vue ciblée avant d'autoriser votre programme de reconnaissance à traiter le toucher. La méthode déléguée pertinente est la suivante :

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

107voto

Clive Paterson Points 550

Le blocage des événements tactiles pour les sous-vues est le comportement par défaut. Vous pouvez modifier ce comportement :

UITapGestureRecognizer *r = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(agentPickerTapped:)];
r.cancelsTouchesInView = NO;
[agentPicker addGestureRecognizer:r];

5voto

joslinm Points 1117

J'affichais une sous-vue de liste déroulante qui avait sa propre vue de table. Par conséquent, le touch.view renvoie parfois des classes comme UITableViewCell . J'ai dû passer en revue la ou les superclasses pour m'assurer qu'il s'agissait bien de la sous-classe que je pensais être :

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    UIView *view = touch.view;
    while (view.class != UIView.class) {
        // Check if superclass is of type dropdown
        if (view.class == dropDown.class) { // dropDown is an ivar; replace with your own
            NSLog(@"Is of type dropdown; returning NO");
            return NO;
        } else {
            view = view.superview;
        }
    }

    return YES;
}

4voto

Caleb Points 72897

Une possibilité est de sous-classer votre reconnaissant de gestes (si vous ne l'avez pas déjà fait) et de surcharger -touchesBegan:withEvent: de sorte qu'il détermine si chaque touche a commencé dans une sous-vue exclue et appelle -ignoreTouch:forEvent: pour cette touche si c'est le cas.

Évidemment, vous devrez également ajouter une propriété pour garder la trace de la sous-vue exclue, ou mieux encore, un tableau de sous-vues exclues.

1voto

Werner Altewischer Points 3439

J'ai créé une sous-classe UIGestureRecognizer conçue pour bloquer tous les reconnaissances de gestes attachés aux supervisions d'une vue spécifique.

Il fait partie de mon projet WEPopover. Vous pouvez le trouver aquí .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X