2011-05-04 15 views
42

Parece que userInteractionEnabled = NO en una vista principal impedirá la interacción del usuario en todas las subvistas. ¿Es esto correcto? ¿Hay alguna forma de evitar esto?UIView - "interacción del usuario habilitada" false en el elemento primario pero verdadero en el elemento secundario?

+4

sí ese es el caso, y eso es completamente estúpido, como tantas cosas en iOS, ¿dónde están los días en que Apple hacía API simples? Supongo que fue hace casi 20 años, ahora las API están escritas por filósofos. –

+4

. . . cuando no están ocupados escribiendo comentarios de desbordamiento de pila. – tooluser

+1

posible duplicado de [Cómo obtener toques cuando la vista principal tiene userInteractionEnabled establecido en NO en iOS] (http://stackoverflow.com/questions/4661589/how-to-get-touches-when-parent-view-has-userinteractionenabled -set-to-no-in-ios) – DBD

Respuesta

27

Correcto, userInteractionEnabled establecido en NO en una vista principal se transferirá en cascada a todas las subvistas. Si necesita algunas subvistas para habilitar la interacción, pero no otras, puede separar sus subvistas en dos vistas principales: una con userInteractionEnabled = YES y la otra NO. Luego ponga esas dos vistas principales en la vista principal.

+1

Gracias lazycs. Mi idea era usar una vista transparente para administrar el diseño de un puñado de vistas de tipo de menú emergente relacionadas. Pero esto no funcionará para mí si la vista de diseño invisible bloquea la interacción con lo que está debajo. Hrrmmmm .... – morgancodes

+1

Sí, la idea de vista transparente no funcionará en este caso. ¿Podría agregar las subvistas a la vista principal directamente? – lazycs

+0

sí, podría hacer. Puede ser mejor utilizar un fondo semitransparente en cualquier caso. No es gran cosa. – morgancodes

13

Puede subclase UIView y anular hitTest: withEvent: en una forma de pasar eventos de toque a una vista que especifique (_backView):

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 
    UIView *view = [super hitTest:point withEvent:event]; 

    if (view == self) { 
     view = _backView; 
    } 

    return view; 
} 

Si el evento tacto era para ser manejado por este punto de vista se pasará a "_backView" (que puede ser un IBOutlet para que se pueda configurar mediante el constructor de interfaz); y si fuera manejado por cualquier vista secundaria simplemente devuelva ese hijo (el resultado de [super hitTest:point withEvent:event];)

Esta solución está bien siempre y cuando sepa a qué vista necesita pasar los eventos; además, no sé si tiene problemas ya que estamos devolviendo una vista (_backView) que no es una subvista del UIView actual. pero funcionó bien en mi caso.

Una mejor solución podría ser la que se menciona en Disable touches on UIView background so that buttons on lower views are clickable Allí se menciona su uso -pointInside:withEvent:; en comparación con la solución anterior es mejor en la forma en que no necesita especificar un '_backView' para recibir los eventos (¡el evento simplemente pasa a la siguiente vista en la cadena)! inconveniente podría ser que tenemos que realizar -pointInside:withEvent: en todas las subvistas (aunque podría ser de una sobrecarga insignificante)

+0

gracias por el enfoque aquí y el enlace "Desactivar toques ...". el enfoque descrito allí parece bastante limpio. –

+0

gran enfoque :) –

+1

hitTest es demasiado tarde ... esta es la mejor respuesta ... http://stackoverflow.com/questions/3427619/disable-touches-on-uiview-background-so-that-buttons-on -lower-views-are-clickabl –

2

Me encontré con una situación extraña. Tengo una UIView (llame esto, V), que tiene un UIButton como subvista. Llame a este UIButton, botón X. A continuación se muestra el método que estoy usando para el destino/selector del botón X. A continuación se muestra la vista V. El parámetro del remitente es el botón X.

La situación que me está causando un problema es que si toco otro botón en mi UI (en la barra de navegación, llamo a este botón Y) y luego presiono el botón X, donde la acción del botón Y desactiva la vista V, aún obtengo el evento táctil enviado al botón X.

- (void) buttonAction: (UIButton *) sender 
{ 
    NSLog(@"superview: %d", sender.superview.userInteractionEnabled); 
    NSLog(@"button itself: %d", sender.userInteractionEnabled); 

    // <snip> 
} 

Aquí está la salida:

2014-12-19 16: 57: 53.826 MyApp [6161: 960615] supervista: 0
19/12/2014 16: 57: 53.826 MiApl [6161: 960615] propio botón: 1

Es decir, se produjo la acción del botón y el botón de supervista había desactivado la interacción con el usuario! ¡Y la subvista todavía tenía habilitada la interacción del usuario!

Para aquellos de ustedes que piensan que esto parece artificial, en la IU de mi aplicación, ejecutándose en un iPad (con iOS 8.1.2), esto ocurrió accidentalmente al usar la aplicación. No era algo que originalmente fui tratando de generar.

¿Pensamientos?

Mi solución actual se detalla a continuación, ¡pero parece realmente extraño que sea necesario!

- (void) buttonAction: (id) sender 
{ 
    NSLog(@"superview: %d", sender.superview.userInteractionEnabled); 
    NSLog(@"button itself: %d", sender.userInteractionEnabled); 
    if (! self.userInteractionEnabled) return; 

    // <snip> 
} 
0

Estoy haciendo esto en un xib que es mi "controlador de alerta personalizado".

for (UIView *subview in self.superview.subviews) { 

    if (![subview isEqual:self]) { 
     subview.userInteractionEnabled = NO; 
    } 
} 
Cuestiones relacionadas