iPhone SDK中的同时手势识别器

26

我需要使用 UISwipeGestureRecognizer 捕获两种不同的滑动手势,例如 UISwipeGestureRecognizerDirectionRightUISwipeGestureRecognizerDirectionLeft。 当我使用 addGestureRecognizer 方法添加两个不同的识别器时,只有最后一个添加的识别器起作用。 我已经阅读过需要实现 UIGestureRecognizerDelegate 协议的 gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: 方法,但是没有任何效果。

有人能提供一个简单的示例来捕获两个或更多相同的手势吗? 谢谢!

5个回答

35

这很简单:

首先,我们应该创建一个实现 UIGestureRecognizerDelegate 协议的类:

@interface MyGestureDelegate : NSObject <UIGestureRecognizerDelegate>

@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;
}

使用方法如下:


    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];


1
谢谢。我刚刚使用这个方法让UIPanGestureRecognizer和UIPinchGestureRecognizer在同一个视图上一起工作了。 - Hafthor
1
要在上面的代码中实现UIGestureRecognizerDelegate,请使用以下代码:@interface MyGestureDelegate : NSObject<UIGestureRecognizerDelegate>。附言:谢谢您的提示... - Steve Parker
我不明白:只有两个识别器中的一个被分配了委托,这是正确的吗? - Sjakelien

20
答案: 来自Phoenix的“嗯,快速查看文档”的答案绝对行不通!他正在设置一个掩码,然后使用同一个变量进行测试,就好像识别器清除了它并设置了单个位。正如他正确地引用文档中所述的那样,它存储了允许的滑动方向。
sender.direction

它只会返回你最初设置的掩码,在他的示例中,永远不会解析为单个方向!

UISwipeGestureRecognizerDirectionRight == 1
UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft == 3

另外,对于大多数情况,您不需要:

  • 设置委托
  • 允许同时手势识别(除非您想进行同时滑动;不太可能)
  • 将识别器发送到选择器

以下代码适用于我:

   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];

是的,对我来说,单独实现手势方向并将它们分配给不同的方法效果很好。虽然有点愚蠢,但确实有效。 - GeneCode
这个答案解决了我的问题,尽管我确实觉得Phoenix的答案应该可以工作。很蠢它不行。 - RyJ

2

嗯,快速查看文档将揭示您正在做比所需更多的工作:

"direction 滑动操作允许的方向。

@property(nonatomic) UISwipeGestureRecognizerDirection direction

讨论 您可以使用按位或操作符指定多个UISwipeGestureRecognizerDirection常量,以指定多个方向。默认方向为UISwipeGestureRecognizerDirectionRight

也就是说,您可以不使用两个UISwipeGestureRecognizers,而只需执行以下操作:

UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc]
                                      initWithTarget:self action:@selector(handleSwipeGesture:)];

 swipeGesture.direction = UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft;

在你的操作方法中:

  -(IBAction)handleSwipeGesture:(UISwipeGestureRecognizer*)sender
     {
     if (sender.direction == UISwipeGestureRecognizerDirectionLeft) {

         //do left action

     } else {

         //do right action

     }
}

更简单,更不容易出现冲突。


1
下面的评论者是正确的。这个程序不会像宣传的那样工作。我应该更仔细地检查我的工作!我把我的大脑波混乱归咎于太阳耀斑... 是的,就是太阳耀斑... 或者其他什么... - Phoenix

1

我建议你稍微了解一下手势识别器用来识别手势的技术。我想,第一个识别器尝试识别手势,但意识到自己不必对其做出反应,然后他就不会将其传递。

阅读它们如何工作非常有用,以便理解如何使用它们。

希望这可以帮到你。


我认为是这样的,在developer.apple.com上有这样的信息: 默认情况下,没有两个手势识别器可以同时尝试识别它们的手势。但是,您可以通过实现UIGestureRecognizerDelegate协议的gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:可选方法来更改此行为。当接收手势识别器的识别将阻止指定手势识别器的操作,或反之亦然时,将调用此方法。返回YES以允许两个手势识别器同时识别其手势。 - user294890

0
感谢user294890的建议,通过从列出的UIGestureRecognizerDelegate方法中返回yes,我成功了。
然而,我发现在网页视图加载前添加手势识别器时无法工作。 当我将手势识别器添加到webView委托方法中时它确实有效: - (void)webViewDidFinishLoad:(UIWebView *)webView

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接