4

我正在实现自定义 UIGestureRecognizer。为简单起见,假设它识别由 >1 次触摸组成的手势。

这是手势.m:

#import "Gesture.h"
#import <UIKit/UIGestureRecognizerSubclass.h>

#define SHOW printf("%s %d %d %d\n", __FUNCTION__, self.state, touches.count, self.numberOfTouches)

@implementation Gesture

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  SHOW;
  if (self.numberOfTouches==1) return;
  self.state = UIGestureRecognizerStateBegan;
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
  SHOW;
  if (self.numberOfTouches==1) return;
  self.state = UIGestureRecognizerStateChanged;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
  SHOW;
  if (self.numberOfTouches==1) return;
  self.state = UIGestureRecognizerStateEnded;
}
@end

这是一个选择器:

- (IBAction)handleGesture:(Gesture *)recognizer {
  printf("%s %d\n", __FUNCTION__, recognizer.state);
}

这是一个输出:

-[Gesture touchesBegan:withEvent:] 0 1 1  // 1st touch began
-[Gesture touchesMoved:withEvent:] 0 1 1
-[Gesture touchesMoved:withEvent:] 0 1 1
-[Gesture touchesMoved:withEvent:] 0 1 1
-[Gesture touchesBegan:withEvent:] 0 1 2  // 2nd touch began
-[Gesture touchesMoved:withEvent:] 1 1 2  // Gesture.state==UIGestureRecognizerStateBegan but selector was not called
-[ViewController handleGesture:] 2        // UIGestureRecognizerStateChanged received.
-[Gesture touchesMoved:withEvent:] 2 2 2
-[ViewController handleGesture:] 2
-[Gesture touchesMoved:withEvent:] 2 2 2
-[ViewController handleGesture:] 2
-[Gesture touchesMoved:withEvent:] 2 2 2
-[ViewController handleGesture:] 3        // UIGestureRecognizerStateEnded received.

为什么选择器不接收 UIGestureRecognizerStateBegan?

4

1 回答 1

3

这对我来说并不是特别明显,但规则似乎是:

  • 通过发送给您的所有触摸touchesBegan:...随后都被视为属于您,除非并且直到您将状态设置为UIGestureRecognizerStateFailedUIGestureRecognizerStateEndedUIGestureRecognizerStateCancelled
  • 相反,如果您转换到,UIGestureRecognizerStateBegan则手势识别器会将其发布,然后在现在分配给您的触摸移动时自动生成。UIGestureRecognizerStateChanged

因此,您不应该UIGestureRecognizerStateChanged为自己设置 - 只需跟踪触摸并正确发布开始、结束、失败和取消。

在您的情况下,我认为您只需要删除touchesMoved:....

(除此之外:iOS 5 和 6 的情况如此;在 4 下,行为稍微微妙一些。要在所有三个版本下工作,请使用结构,例如if(self.state == UIGestureRecognizerStateBegan) self.state = UIGestureRecognizerStateChanged;当您知道您的属性已更改时)

于 2012-11-13T21:21:24.543 回答