2010-09-06 11 views
5

Tengo una UIView que tiene un montón de subvistas. Las subvistas deberían poder recibir eventos táctiles, pero por alguna razón el UIView padre toma el tacto y no lo transmite. He creado de una manera muy estándar como siempre crear vistas:iphone/ipad - padre UIView está bloqueando los toques para llegar a las subvistas - ¿por qué?

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

    [self.view addSubview:self.mainView]; 

Entonces creo subvistas y añadirlos de forma normal:

[self.mainView addSubview:someOtherView]; 

Sé self.mainView está recibiendo los eventos táctiles cuando escucho en el UIWindow principal:

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

Pero ¿por qué en el mundo no puedo conseguir los subvistas para recibir toques? No entiendo por qué sucede esto a veces. No estoy cambiando ninguna propiedad predeterminada de mainView.

Respuesta

15

Tenían que ver con el marco de la vista principal. Si el marco no encierra las subvistas, no recibirán toques.

+1

también tenga en cuenta los "límites" de su vista principal cuando coloque sus subvistas en la pantalla. Su marco puede o no ser la posición real en la pantalla. – MOK9

+0

@sol: ¿Cómo sabes si ese es el caso? – moonman239

0

¿Toca controladores que llaman a los controladores de superclase?

p. Ej. en sus toques Bean, llamando al:

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

No tengo manipuladores táctiles. Las subvistas simplemente no responden a los toques. Por ejemplo, un GestureRecognizer en una de las subvistas no funciona. – sol

12

Los toques UIView no se pasan a las subvistas si se encuentran fuera de los límites de la supercomprobación según lo mencionado por la solución.

Sin embargo, si desea que estas subcarpetas respondan al tacto, anule hitTest:withEvent: de la supervista.

Documentation on Event Delivery

eventos táctiles. El objeto ventana utiliza la prueba de aciertos y la cadena de respuesta para encontrar la vista que recibirá el evento táctil. En la prueba de aciertos, una ventana llama a HitTest: withEvent: en la vista superior de la jerarquía de vistas; este método procede llamando recursivamente a pointInside: withEvent: en cada vista en la jerarquía de vista que devuelve SÍ, avanzando hacia abajo en la jerarquía hasta que encuentra la subvista dentro de cuyos límites se realizó el toque. Esa vista se convierte en la vista de prueba de golpe.

  1. crear una subclase de UIView (u otra subclase UIView).
  2. Anular hitTest: withEvent.
  3. Utilice esta subclase UIView como la supervista, para que la subvista pueda responder a los toques.

método Add a continuación en la subclase:

(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: empadronador inversa utilizado desde subvistas se ordenan de atrás hacia delante y queremos poner a prueba el frente más vista en primer lugar.

+0

Esto funcionó para mí. ¡Gracias por publicar esto! – tjg184

Cuestiones relacionadas