recognizer react gesturerecognizer iphone cocoa-touch uiview uigesturerecognizer

iphone - react - ¿Cómo encontrar de forma confiable la vista correcta para UIGestureRecognizer?



tap gesture recognizer swift 4 (3)

Tengo un montón de UIViews como en la imagen de abajo. La vista roja / rosa (semitransparente) está sobre las otras.

  • Rojo tiene un UISwipeGestureRecognizer .
  • El verde tiene como UITapGestureRecognizer .
  • El azul no tiene reconocedor.

Un toque en la parte visible (parte inferior izquierda) de Green dispara su reconocedor.

Un toque en las partes ocultas de Green no dispara su reconocedor (Red lo bloquea).

Ese es el problema: quiero que el verde se dispare. ¿Cómo puedo hacer esto?

En la práctica, las vistas pueden estar en cualquier orden, cualquier número y ser subvistas de otras, etc. Pero el problema es el mismo:

¿Cómo puedo encontrar de manera confiable la vista superior que puede manejar el gesto (tocar o deslizar)?

He intentado con el código de abajo. Atraviesa perfectamente todas las vistas, pero falla, ya que no puede saber si el evento es parte de un golpe o un toque. Así que el método siempre devuelve la vista roja. Si quito el reconocedor de deslizamiento de Rojo, el código funciona correctamente.

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *hitView = [super hitTest:point withEvent:event]; if (hitView == self) { if (self.hasASwipeRecognizer) return self; // What if this was a tap? if (self.hasATapRecognizer) return self; else return nil; } else return hitView; }


Mis soluciones son:

-(void)handleGesture:(UIGestureRecognizer*)gestureRecognizer { CGPoint touchPoint = [tapGestureRecognizer locationInView:viewUnderTest]; if ([viewUnderTest pointInside:touchPoint withEvent:nil]) { NSLog(@"Hit done in view under test"); } }


Una alternativa a agregar el reconocedor de gestos a estas vistas sería agregar los reconocedores de gestos a la vista principal y manejar los casos de uso de manera apropiada utilizando el método delegado gestureRecognizer:shouldReceiveTouch: método.

Identifique si el reconocedor en particular debe recibir el toque y devolver YES . Por ejemplo, si el reconocedor de gestos pasado es un reconocedor de barrido, verifique si el punto de contacto está dentro de la vista verde y devuelva YES . Vuelva NO contrario.

Si hay reconocedores de gestos similares, le sugiero que guarde una referencia y verifique que no haya ninguna.

Uso

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { CGPoint pointInView = [touch locationInView:gestureRecognizer.view]; if ( [gestureRecognizer isMemberOfClass:[UITapGestureRecognizer class]] && CGRectContainsPoint(self.blueView.frame, pointInView) ) { return YES; } if ( [gestureRecognizer isMemberOfClass:[UISwipeGestureRecognizer class]] && CGRectContainsPoint(self.greenView.frame, pointInView) ) { return YES; } return NO; }


Una posible solución sería agregar un reconocedor de gestos de toque a la vista roja superior y luego, cada vez que obtenga el toque, verifique si el punto de toque se cruza con la vista verde. Si es así, reenvíe el grifo a esa vista. Si no, ignora el grifo.