Eu tenho uma hierarquia de visualização parecida com esta:
UIView (A)
UIView > UIImageView
UIView > UIView (B)
UIView > UIView (B) > Rounded Rect Button
UIView > UIView (B) > UIImageView
UIView > UIView (B) > UILabel
Anexei reconhecedor (es) de gestos ao meu UIView (B). O problema que estou enfrentando é que não consigo nenhuma ação para o Botão Reto Arredondado que está dentro do UIView (B). O reconhecedor de gestos singleTap captura / substitui o evento Touch Up Inside do botão.
Como posso fazer funcionar? Eu pensei que a hierarquia da cadeia de resposta garantirá que o evento de toque do botão terá preferência e será acionado! O que estou perdendo?
Aqui estão alguns códigos relacionados:
#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;
}
}
Respostas:
No método "shouldReceiveTouch" você deve adicionar uma condição que retornará NÃO se o toque for no botão.
Isso é do exemplo SimpleGestureRecognizers da apple .
espero que ajude
Editar
Como Daniel observou, você deve estar em conformidade
UIGestureRecognizerDelegate
para que funcione.Shani
fonte
if ( [touch.view isKindOfClass:[UIControl class]] || [[touch.view superview] isKindOfClass:[UITableViewCell class]] ) {
... Observe que as células tableview são "tocadas" em seu contentView, que é membro de uma classe privada, então lá verificamos a classe do superview.Eu também tive o mesmo problema, então tentei com
Agora está funcionando perfeitamente .........
fonte
myGestureRecognizer.delegate = self;
De um modo geral, usamos o método delegado abaixo para evitar o toque em todos os tipos de UIControls:
Nota: NÃO faça esta verificação (verifique o tipo de classe reconhecizer.view) o gestoRecognizerShouldBegin, ele não funcionará.
fonte
Aqui está uma versão do Swift 3.0 :
Não se esqueça de:
Make your tapper object delegate to self (e.g: tapper.delegate = self)
fonte
Aqui está uma versão Swift:
Não se esqueça de:
UIGestureRecognizerDelegate
tapper.delegate = self
:)fonte
A melhor solução, em minha opinião, é usar o snippet de código abaixo:
fonte