iphone - plus - Deshabilite los toques en el fondo UIView para que se pueda hacer clic en los botones de las vistas inferiores
sensibilidad pantalla iphone 6 plus (4)
Básicamente, aquí está mi jerarquía de vistas (y pido disculpas si es difícil de leer ... Soy nuevo aquí, así que estoy aceptando sugerencias de publicación)
--AppControls.xib
------- (UIView) ControlsView
----------------- (UIView) TopBar
----------------- -------------- btn1, btn2, btn3
----------------- UIView) BottomBar
----------------- -------------- slider1 btn1, btn2
--PageContent.xib
----------------- (UIView) ContentView
----------------- -------------- btn1, btn2, btn3
----------------- -------------- (UIImageView) FullPageImage
Mi situación es que quiero ocultar y mostrar los controles al tocar en cualquier parte del contenido de PageContent que no sea un botón y que se muestren los controles, como en el iPhone Video Player. Sin embargo, cuando se muestran los controles, todavía quiero poder hacer clic en los botones del contenido de la página.
Tengo todo esto funcionando, excepto el último bit. Cuando los controles muestran el fondo de los controles, recibe los eventos táctiles en lugar de la vista a continuación. Y al desactivar la interacción del usuario en ControlsView, se desactiva en todos sus hijos.
He intentado anular HitTest en mi subclase de ControlsView de la siguiente manera que encontré en una publicación similar:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
UIView *hitView = nil;
NSArray *subviews = [self subviews];
int subviewCount = [subviews count];
for (int subviewIndex = 0; !hitView && subviewIndex < subviewCount; subviewIndex++){
hitView = [[subviews objectAtIndex:subviewIndex] hitTest:point withEvent:event];
}
return hitView;
}
Sin embargo, en este punto, mi control deslizante no funciona, ni tampoco la mayoría de los otros botones, y realmente, las cosas empiezan a ponerse raras.
Entonces, mi pregunta es breve: ¿Cómo puedo permitir que todas las subvistas de una vista tengan eventos táctiles, mientras que el fondo de la súper vista no se puede hacer clic y los botones de las vistas a continuación pueden recibir eventos táctiles?
¡Gracias!
Estás cerca. No -hitTest:withEvent:
Cuando se llama, el despachador de eventos ya ha decidido que su subárbol de la jerarquía es el propietario del evento y no buscará en ningún otro lugar. En su lugar, -pointInside:withEvent:
que se llama anteriormente en el proceso de procesamiento de eventos. Así es como el sistema pregunta "hey view, ¿ALGUIEN en tu jerarquía responde a un evento en este momento?". Si dices NO, el procesamiento de eventos continúa por debajo de ti en la pila visible.
Según la documentation , la implementación predeterminada solo verifica si el punto está en los límites de la vista.
Su estrategia es decir "sí" cuando cualquiera de sus subvistas esté en esa coordenada, pero diga "no" cuando el toque toque el fondo.
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
for (UIView * view in [self subviews]) {
if (view.userInteractionEnabled && [view pointInside:[self convertPoint:point toView:view] withEvent:event]) {
return YES;
}
}
return NO;
}
Gracias a @Ben Zutto, solución Swift 3:
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
for view in self.subviews {
if view.isUserInteractionEnabled, view.point(inside: self.convert(point, to: view), with: event) {
return true
}
}
return false
}
Otro enfoque puede ser tener un botón invisible de pantalla completa detrás de todo lo demás y tomar las medidas apropiadas cuando se golpea.
Una variante leve en la respuesta de Ben, que trata con los hijos que se extienden fuera de sus padres. Si clipChildren es SÍ, esto no devolverá SÍ a los puntos que están fuera del control principal pero dentro de algún niño. si clipChildren es NO, esto es lo mismo que el de Ben.
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
BOOL clipChildren = YES;
if (!clipChildren || [super pointInside:point withEvent:event]) {
for (UIView * view in [self subviews]) {
if (view.userInteractionEnabled && [view pointInside:[self convertPoint:point toView:view] withEvent:event]) {
return YES;
}
}
}
return NO;
}