2010-09-06 3 views
5

J'ai un UIView qui a un tas de sous-vues. Les sous-vues devraient pouvoir recevoir des événements tactiles, mais pour une raison quelconque, le parent UIView prend le contact et ne le transmet pas. Je l'ai créé en créer plus standard comme je l'ai toujours vue:iphone/ipad - parent UIView bloque les touches pour accéder aux sous-vues - pourquoi?

UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0,0,1024,768)]; 
    self.mainView = myView; 
    [myView release]; 

    [self.view addSubview:self.mainView]; 

Puis-je créer des sous-vues et les ajouter comme d'habitude:

[self.mainView addSubview:someOtherView]; 

Je sais que self.mainView obtient les événements tactiles lorsque J'écoute dans la principale UIWindow:

VIEW: <UIView: 0x8d34aa0; frame = (0 0; 1024 768); 

Mais pourquoi dans le monde ne puis-je obtenir les sous-vues pour recevoir des touches? Je ne comprends pas pourquoi cela arrive parfois. Je ne change pas les propriétés par défaut de mainView.

Répondre

15

A dû faire avec le cadre de la vue parente. Si le cadre ne contient pas les sous-vues, il ne recevra aucune touche.

+1

gardez également à l'esprit de référencer les 'limites' de votre vue parente lorsque vous positionnez vos sous-vues à l'écran. Votre cadre peut ou peut ne pas être la position réelle sur l'écran. – MOK9

+0

@sol: Comment savez-vous si c'est le cas? – moonman239

0

Est-ce que les gestionnaires tactiles appellent les gestionnaires de la super-classe?

par exemple. dans vos touchesBegan, appelant:

[super touchesBegan:touches withEvent:event]; 
+0

Je n'ai pas de manipulateur tactile. Les sous-vues ne répondent tout simplement pas aux touches. Par exemple, un GestureRecognizer sur l'une des sous-vues ne fonctionne pas. – sol

12

Les touches UIView ne sont pas transmises aux sous-vues si elles se trouvent en dehors des limites de la vue supérieure, comme indiqué par la solution. Toutefois, si vous souhaitez que ces sous-vues répondent au toucher, remplacez hitTest:withEvent: de la vue supérieure.

Documentation on Event Delivery

événements tactiles. L'objet window utilise le test d'impact et la chaîne du répondeur pour trouver la vue permettant de recevoir l'événement tactile. Dans le hit-test, une fenêtre appelle hitTest: withEvent: sur l'affichage le plus haut de la hiérarchie de vue; cette méthode procède en appelant récursivement pointInside: withEvent: sur chaque vue de la hiérarchie de vue qui renvoie YES, en descendant la hiérarchie jusqu'à ce qu'elle trouve la sous-vue dans les limites de laquelle le contact a eu lieu. Cette vue devient la vue hit-test.

  1. Créer une sous-classe de UIView (ou autre sous-classe UIView).
  2. Remplacer hitTest: withEvent.
  3. Utilisez cette sous-classe UIView comme superview, de sorte que la sous-vue puisse répondre aux touches.

méthode Add ci-dessous dans la sous-classe:

(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    NSEnumerator *reverseE = [self.subviews reverseObjectEnumerator]; 
    UIView *iSubView; 

    while ((iSubView = [reverseE nextObject])) { 

     UIView *viewWasHit = [iSubView hitTest:[self convertPoint:point toView:iSubView] withEvent:event]; 
     if(viewWasHit) { 
      return viewWasHit; 
     } 

    } 
    return [super hitTest:point withEvent:event]; 
} 

Note: recenseur inverse utilisé depuis subviews sont commandés d'arrière en avant et nous voulons tester la plus vue de l'avant première.

+0

Cela a fonctionné pour moi. Merci de l'avoir posté! – tjg184

Questions connexes