4

カスタム UIGestureRecognizer を実装しています。簡単にするために、1 回以上のタッチで構成されるジェスチャを認識すると仮定します。

Gesture.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 未満では、動作は少し微妙です。3 つのバージョンすべてで動作するにはif(self.state == UIGestureRecognizerStateBegan) self.state = UIGestureRecognizerStateChanged;、プロパティが変更されたことを知っている場合のような構造を使用します)

于 2012-11-13T21:21:24.543 に答える