Tengo una jerarquía de vistas que se parece a esto:
UIView (A)
UIView > UIImageView
UIView > UIView (B)
UIView > UIView (B) > Rounded Rect Button
UIView > UIView (B) > UIImageView
UIView > UIView (B) > UILabel
Adjunté reconocedores de gestos a mi UIView (B). El problema al que me enfrento es que no obtengo ninguna acción para el botón Rect redondeado que está dentro de UIView (B). El reconocedor de gestos singleTap captura / anula el evento Touch Up Inside del botón.
¿Cómo puedo hacer que funcione? Pensé que la jerarquía de la cadena de respuesta se asegurará de que se dé preferencia al evento de toque de botón, ¡y se activará! ¿Qué me estoy perdiendo?
Aquí hay un código relacionado:
#pragma mark -
#pragma mark View lifecycle (Gesture recognizer setup)
- (void)viewDidLoad {
[super viewDidLoad];
// double tap gesture recognizer
UITapGestureRecognizer *dtapGestureRecognize = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapGestureRecognizer:)];
dtapGestureRecognize.delegate = self;
dtapGestureRecognize.numberOfTapsRequired = 2;
[self.viewB addGestureRecognizer:dtapGestureRecognize];
// single tap gesture recognizer
UITapGestureRecognizer *tapGestureRecognize = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureRecognizer:)];
tapGestureRecognize.delegate = self;
tapGestureRecognize.numberOfTapsRequired = 1;
[tapGestureRecognize requireGestureRecognizerToFail:dtapGestureRecognize];
[self.viewB addGestureRecognizer:tapGestureRecognize];
// add gesture recodgnizer to the grid view to start the edit mode
UILongPressGestureRecognizer *pahGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGestureRecognizerStateChanged:)];
pahGestureRecognizer.delegate = self;
pahGestureRecognizer.minimumPressDuration = 0.5;
[self.viewB addGestureRecognizer:pahGestureRecognizer];
[dtapGestureRecognize release];
[tapGestureRecognize release];
[pahGestureRecognizer release];
}
#pragma mark -
#pragma mark Button actions
- (IBAction)buttonTouchUpInside:(id)sender {
NSLog(@"%s, %@", __FUNCTION__, sender);
}
#pragma mark -
#pragma mark Gesture recognizer actions
- (void)singleTapGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
NSLog(@"%s", __FUNCTION__);
}
- (void)doubleTapGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
NSLog(@"%s", __FUNCTION__);
}
- (void)longPressGestureRecognizerStateChanged:(UIGestureRecognizer *)gestureRecognizer {
switch (gestureRecognizer.state) {
case UIGestureRecognizerStateEnded: {
NSLog(@"%s", __FUNCTION__);
break;
}
default:
break;
}
}
Respuestas:
En el método "shouldReceiveTouch" debe agregar una condición que devolverá NO si el toque está en el botón.
Esto es del ejemplo de Apple SimpleGestureRecognizers .
espero que ayude
Editar
Como señaló Daniel, debes ajustarte a
UIGestureRecognizerDelegate
ello para que funcione.shani
fuente
if ( [touch.view isKindOfClass:[UIControl class]] || [[touch.view superview] isKindOfClass:[UITableViewCell class]] ) {
... Tenga en cuenta que las celdas de la vista de tabla se "tocan" en su vista de contenido, que es miembro de una clase privada, así que allí verificamos la clase de la supervista.También tuve el mismo problema, luego intenté con
Ahora está funcionando perfectamente .........
fuente
myGestureRecognizer.delegate = self;
En términos generales, utilizamos el siguiente método de delegado para evitar el toque en todo tipo de UIControls:
Nota: NO haga esta verificación (verifique el tipo de clase Recognizer.view) el gestoRecognizerShouldBegin, no funcionará.
fuente
Aquí hay una versión de Swift 3.0 :
No olvide:
Make your tapper object delegate to self (e.g: tapper.delegate = self)
fuente
Aquí hay una versión Swift:
No olvide:
UIGestureRecognizerDelegate
tapper.delegate = self
)fuente
En mi opinión, la mejor solución es usar el siguiente fragmento de código:
fuente