uigesturerecognizerdelegate example objective-c xcode uiview uigesturerecognizer

objective c - example - Excluir subvistas de UIGestureRecognizer



uitapgesturerecognizer swift (8)

ADICIONAL:

Acabo de pensar en algo mejor.

en su controlador

-(void)tapGestureHandler:(UITapGestureHandler)gesture

Compruebe si gesto.view es la supervisión. devolverá las subvistas si las subvistas se tocan.

=============================================== ==

Yo sugeriría anular dentro de la supervisión.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

Esto se llama para determinar si un gesto cae dentro de una vista.

Consulte la respuesta a esta pregunta para ver cómo se comporta de forma predeterminada.

Manejo de eventos para iOS: ¿cómo se relacionan las pruebas hitTest: withEvent: and pointInside: withEvent?

puedes verificar si el punto está en alguna de sus subvistas. Si es así, devuelve cero, o si no, vuelve a ti mismo.

O

en cada una de las subvistas, agregue un reconocedor de tapgestura que no haga nada. el reconocedor de gestos de una subvista cancelará el reconocedor de gestos de su supervisión de forma predeterminada. Sin embargo, mantendría un ojo en la huella de memoria si hay muchas subvistas.

Tengo un UIView (la ''vista de contenedor'') que contiene varias ''subvistas''. Quiero agregar un UITapGestureRecognizer a la vista de contenedor, de modo que se active cuando toco la región dentro de la vista de contenedor pero fuera de las subvistas.

En este momento, al tocar en cualquier lugar dentro de la vista del contenedor, incluso dentro de las subvistas, se activa el reconocedor de gestos.

La implementación se ve algo como esto: En el controlador:

ContainerView *containerView = [[ContainerView alloc] initWithSubViews:array]; UITapGestureRecognizer *tap = [UITapGestureRecognizer alloc] initWithTarget:self action:@selector(someSelector)]; [containerView addGestureRecognizer:tap]; [self.view addSubView:containerView];

En ContainerView.m

-(id)initWithSubviews:(NSArray *)array { for (subView *s in array) { [self addSubView:s]; } return self; }

Creo que el problema ocurre porque el reconocedor de gestos se agrega después de las subvistas. Si eso es cierto, entonces la solución requeriría dividir el método initWithSubViews en dos métodos diferentes, que preferiría evitar.

Gracias


Logré que funcionara haciendo lo siguiente:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureHandler:)]; // ... -(void) tapGestureHandler:(UITapGestureRecognizer *)sender { CGPoint point = [sender locationInView:sender.view]; UIView *viewTouched = [sender.view hitTest:point withEvent:nil]; if ([viewTouched isKindOfClass:[ThingIDontWantTouched class]]) { // Do nothing; } else { // respond to touch action } }


Muchas respuestas, añadiendo otra solución alternativa. Inicialice la etiqueta de vista de las subvistas de las que no quiere recibir toques como 1 y haga lo siguiente:

- (void)viewDidLoad { [super viewDidLoad]; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; tap.delegate = self; [self.view addGestureRecognizer:tap]; } -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if (touch.view.tag == 1) { return NO; } return YES; } -(void)handleTap:(id)sender { //Handle tap... }

De esta manera, el gesto táctil se recibirá solo desde las vistas que lo requiera.


Respuesta actualizada para Swift 4

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { if touch.view != yourView { return false } return true }

Antes de eso, asegúrese de que tiene la propiedad de delegado de configuración para su objeto.


Si agregó UITapGestureRecognizer for ContainerView, debería responder con ContainerView. No le importarán sus subvistas.

Verifique la ubicación del gesto, si está en su posición de subvista, simplemente omita las acciones del gesto.

- (void) tapGestureHandler:(UIGestureRecognizer *) gestureRecognizer { CGPoint tapPoint = [gestureRecognizer locationInView:nil]; //check your tapPoint contains ur subview frame, skip.else do ur actions }


Utilicé la manera simple a continuación. ¡Funciona perpectly!

Implementar la función UIGestureRecognizerDelegate, aceptar solo toques en supervisar, no aceptar toques en subvistas:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if (touch.view != _mySuperView) { // accept only touchs on superview, not accept touchs on subviews return NO; } return YES; }


iOS 6 presenta una nueva y fantástica característica que resuelve este problema exacto: una UIView (subvista) puede devolver NO desde gestos de reconocimiento de inicio de página gestureRecognizerShouldBegin: (reconocedor de gestos adjunto a una vista de supervisión). De hecho, ese es el valor predeterminado para algunas subclases UIView con respecto a algunos reconocedores de gestos ya (por ejemplo, un UIButton con respecto a un UITapGestureRecognizer adjunto a una supervisión).

Vea mi libro sobre este tema: http://www.apeth.com/iOSBook/ch18.html#_gesture_recognizers


Recuerde agregar y configurar el método de delegado -

En su archivo .h de UIViewController incluya este delegado

@interface YourViewController: UIViewController<UIGestureRecogniserDelegate>

Luego, donde está creando su objeto tapGesture, (dentro de viewDidLoad, por ejemplo)

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(actionMethodYouWantToHappenOnTap)]; tap.delegate = self; //Remember to set delegate! Otherwise the delegate method won''t get called. [self.view addGestureRecognizer:tap];

Recordando establecer el método delegado tap.delegate = self; entonces el método de delegado para tap se activará ahora.

Dentro de este método, usted maneja cuándo desea que se use el reconocimiento de gestos de toque, en mi código quería ignorar un toque si una subvista particular estaba visible

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ if (!mySubview.hidden){ return NO; //This fired if said subview was visible, though whatever the condition of where and when you want tap to work, can be handled within this delegate method. } return YES; }

Espero que esto ayude a alguien más con el mismo problema. Recordar establecer el método de delegado que encontré fue algo que se pasa por alto fácilmente.

Aclamaciones