2011-01-28 12 views
94

que tienen una jerarquía de vistas que se ve algo como esto:acciones reconocedor y botón Gesto

UIView (A) 
UIView > UIImageView 
UIView > UIView (B) 
UIView > UIView (B) > Rounded Rect Button 
UIView > UIView (B) > UIImageView 
UIView > UIView (B) > UILabel 

He adjuntado reconocedor (s) gesto a mi UIView (B). El problema que estoy enfrentando es que no obtengo ninguna acción para el Botón de Rectángulo 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ía de que al evento de toque de botón se le dé preferencia, 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; 
    } 
} 
+0

La forma más sencilla es configurar cancelsTouchesInView = false –

Respuesta

165

En el método "shouldReceiveTouch" se debe añadir una condición que no devolverá si el contacto está en el botón.

Esto es de apple SimpleGestureRecognizers ejemplo.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { 

    // Disallow recognition of tap gestures in the segmented control. 
    if ((touch.view == yourButton)) {//change it to your condition 
     return NO; 
    } 
    return YES; 
} 

esperan que ayude a

Editar

Como señaló Daniel debe ajustarse a UIGestureRecognizerDelegate para que funcione.

Shani

+1

Ah !!! Sí, me olvidé de este -gestureRecognizer: shouldReceiveTouch: método. Gracias por señalarme en la dirección correcta. Aunque esto resuelve mi problema, pero todavía no sé por qué la jerarquía de respuesta no funciona en este caso. Probablemente debería, pero no está siendo manejado por Apple. – Mustafa

+2

El comportamiento de UIGestureRecognizer se describe claramente como separado de la cadena de respondedores "normal". Esta es una decisión de diseño de Apple. –

+9

Recuerde cumplir con el protocolo UIGestureRecognizerDelegate y configure el delegado de UIGestureRecognizer para ese objeto. – Daniel

48

También tuve el mismo problema, he intentado con

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{ 

    if ([touch.view isKindOfClass:[UIButton class]]) {  //change it to your condition 
     return NO; 
    } 
    return YES; 
} 

Se está trabajando ahora perfectamente .........

+2

me perdí el 'myGestureRecognizer.delegate = self;' – zero3nna

18

En términos generales, usamos a continuación el método delegado para evitar el contacto en todo tipo de UIControls:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { 
    if (([touch.view isKindOfClass:[UIControl class]])) { 
     return NO; 
    } 
    return YES; 
} 

Nota: NO hacer esta comprobación (c diablos el tipo de clase recognizer.view) el gestureRecognizerShouldBegin, no funcionará.

4

La mejor solución es el uso de mi mente siguiente fragmento de código:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { 
    CGPoint touchLocation = [touch locationInView:self.view]; 
    return !CGRectContainsPoint(self.menuButton.frame, touchLocation); 
} 
6

Aquí es una versión Swift:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool { 
    if (touch.view!.isKindOfClass(UIButton)) { 
     return false 
    } 
    return true 
} 

No se olvide de:

  1. que usted hace la clase se ajusta a UIGestureRecognizerDelegate
  2. Haga su objeto del golpeador legate a self (por ejemplo: tapper.delegate = self)
6

Aquí hay un Swift 3.0 versión:

extension UIViewController: UIGestureRecognizerDelegate { 

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { 
    if touch.view is UIButton { 
     return false 
    } 
    return true 
} 

No se olvide de:

Make your tapper object delegate to self (e.g: tapper.delegate = self)

Cuestiones relacionadas