2010-09-06 7 views
5

Ho un UIView che ha un mucchio di sotto-visualizzazioni. Le sottoview dovrebbero essere in grado di ricevere eventi tattili, ma per qualche motivo la UIView genitore prende il tocco e non la trasmette. Ho creato in un modo molto standard come ho sempre creare viste:iphone/ipad - genitore UIView sta bloccando i tocchi da ottenere a subviews - perché?

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

    [self.view addSubview:self.mainView]; 

Poi creo subviews e aggiungerli come normale:

[self.mainView addSubview:someOtherView]; 

So self.mainView sta ottenendo gli eventi tatto quando ascolto nella UIWindow principale:

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

Ma perché nel mondo non posso ottenere i subviews per ricevere tocchi? Non capisco perché questo capita a volte. Non sto cambiando nessuna proprietà di default di mainView.

risposta

15

Aveva a che fare con il frame della vista padre. Se la cornice non racchiude le sottoview non riceveranno tocchi.

+1

Ricorda inoltre di fare riferimento ai "limiti" della tua vista genitore quando posizioni i tuoi sottoview sullo schermo. La cornice potrebbe essere o meno la posizione effettiva sullo schermo. – MOK9

+0

@sol: come fai a sapere se è così? – moonman239

0

Si toccano i gestori chiamano i gestori della superclasse?

ad es. nei tuoi tocchiBegan, chiamando:

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

Non ho alcun operatore di tocco. Le sottoview semplicemente non rispondono ai tocchi. Ad esempio un GestureRecognizer su una delle subviews non funziona. – sol

12

I tocchi di UIView non vengono trasmessi a subview se si trovano al di fuori dei confini della superview come menzionato dalla soluzione.

Tuttavia, se si desidera che queste sottoview rispondano al tocco, ignorare hitTest:withEvent: del superview.

Documentation on Event Delivery

eventi di tocco. L'oggetto window utilizza hit-testing e la catena responder per trovare la vista per ricevere l'evento touch. In hit-testing, una finestra chiama hitTest: withEvent: nella parte superiore della vista della gerarchia della vista; questo metodo procede ricorsivamente chiamando pointInside: withEvent: su ogni vista nella gerarchia della vista che restituisce SÌ, procedendo lungo la gerarchia finché non trova la sottoview entro cui si è verificato il tocco. Quella vista diventa la vista hit-test.

  1. creare una sottoclasse di UIView (o altro sottoclasse UIView).
  2. Override hitTest: withEvent.
  3. Utilizzare questa sottoclasse UIView come superview, in modo che la sottoview possa rispondere ai tocchi.

Add metodo seguito nella sottoclasse:

(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]; 
} 

Nota: enumerator inversione utilizzato fin subviews sono ordinati da dietro in avanti e vogliamo testare il fronte più vista prima.

+0

Questo ha funzionato per me. Grazie per aver postato questo! – tjg184

Problemi correlati