Reconhecedores de gestos simultâneos no iPhone SDK

Eu preciso pegar dois gestos diferentes swipping usando UISwipeGestureRecognizer (por exemplo, UISwipeGestureRecognizerDirectionRight e UISwipeGestureRecognizerDirectionLeft ). Quando adiciono dois reconhecedores diferentes com o método addGestureRecognizer , apenas o último reconhecedor adicionado funciona. Eu li que preciso implementar o método gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer: do protocolo UIGestureRecognizerDelegate , mas nada funciona.

Alguém pode ajudar com um exemplo simples de pegar dois ou mais gestos iguais? Obrigado!

Foi muito fácil:

Em primeiro lugar, devemos criar uma class que implemente o protocolo UIGestureRecognizerDelegate :

 @interface MyGestureDelegate : NSObject  
@implementation MyGestureDelegate - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ return YES; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ return YES; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{ return YES; }
@implementation MyGestureDelegate - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ return YES; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ return YES; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{ return YES; } 

E usá-lo assim:

UISwipeGestureRecognizer *swipeGestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGestureLeft:)]; [self.view addGestureRecognizer:swipeGestureLeft]; swipeGestureLeft.direction = UISwipeGestureRecognizerDirectionLeft; [swipeGestureLeft release]; UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)]; swipeGesture.direction = UISwipeGestureRecognizerDirectionRight; [self.view addGestureRecognizer:swipeGesture]; MyGestureDelegate *deleg = [[MyGestureDelegate alloc] init]; [swipeGesture setDelegate:deleg]; [swipeGesture release]; 

A resposta: “Hum, um rápido olhar para a documentação …” de Phoenix absolutamente não vai funcionar!

Ele está definindo uma máscara e, em seguida, usando a mesma variável para testar como se o reconhecedor tivesse limpado e definido um único bit. Ele armazena, como ele citou corretamente a documentação:

As direções permitidas do furto

 sender.direction 

irá simplesmente retornar a máscara que você definiu inicialmente e, no seu exemplo, nunca irá resolver para uma única direção!

 UISwipeGestureRecognizerDirectionRight == 1 UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft == 3 

Além disso, na maioria dos casos, você não precisa:

  • configurar um delegado
  • permitir o reconhecimento simultâneo de gestos (a menos que você queira furto simultâneo; não é provável)
  • enviar o reconhecedor para o seletor

O seguinte funciona para mim:

  UISwipeGestureRecognizer* swipe; swipe = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeL)] autorelease]; swipe.direction = UISwipeGestureRecognizerDirectionLeft; [view addGestureRecognizer:swipe]; swipe = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeR)] autorelease]; swipe.direction = UISwipeGestureRecognizerDirectionRight; // default [view addGestureRecognizer:swipe]; 

Um rápido olhar para a documentação revelaria que você está fazendo muito mais trabalho do que precisa:

“direction As direções permitidas do furto.

 @property(nonatomic) UISwipeGestureRecognizerDirection direction 

Discussão Você pode especificar várias direções especificando várias constantes UISwipeGestureRecognizerDirection usando operandos OR bit a bit. A direção padrão é UISwipeGestureRecognizerDirectionRight . ”

O que significa que, em vez de usar dois UISwipeGestureRecognizers, você pode apenas fazer o seguinte:

 UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)]; swipeGesture.direction = UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft; 

E no seu método de ação:

  -(IBAction)handleSwipeGesture:(UISwipeGestureRecognizer*)sender { if (sender.direction == UISwipeGestureRecognizerDirectionLeft) { //do left action } else { //do right action } } 

Muito mais simples e muito menos propenso a conflitos.

Eu sugiro que você leia um pouco sobre a técnica que os reconhecedores de gestos usam para reconhecer o gesto. Eu suponho, o primeiro reconhecedor tenta reconhecer o gesto, mas percebe que ele não tem que responder a ele e, em seguida, de alguma forma ele não o passa adiante.

É muito útil ler como eles funcionam para entender como usá-los.

Espero que isto ajude.

Graças à sugestão do user294890, obtive êxito retornando yes dos methods UIGestureRecognizerDelegate listados.

No entanto, achei que não funcionaria quando eu estava adicionando o GestureRecognizer antes que a visualização da Web fosse carregada. No entanto, funcionou quando adicionei o GestureRecognizer ao webView no método delegado webView:

- (void)webViewDidFinishLoad:(UIWebView *)webView .