AppleのUIGestureRecognizerのデザインは非常に素晴らしく、拡張可能だと思います。
アイデアは、ジェスチャ(またはインタラクション)の認識とトリガーされるアクションを分離することです。
イベントMousePressEvent、MouseReleaseEvent MouseMoveEvent、MouseWheelEventなどに基づいて特定のインタラクションまたはジェスチャを認識できる基本または抽象GestureRecognizerクラスを実装する必要があります。GestureRecongnizersには、変更を定期的に報告するターゲットがあります。
たとえば、非常に基本的なクラスは次のようになります:(私の貧弱なsemi c ++疑似コード...最近はあまり使用していません)
class Recognizer {
int state; // ex: 0:possible, 1:began, 2:changed, 3:ended/recognized 4:cancelled
protected:
void setTarget(void &theTarget); // or even better a touple, target/method. In this case target is assumed to have a method gestureHandle(Recognizer *r);
virtual void mouserPress() = 0;
virtual void mouserRelease() = 0;
virtual void mouserMove() = 0;
virtual void mouserWheel() = 0;
...
}
また、マウスでスワイプを検出したい場合
class SwipeRecognizer : Recognizer {
int direction; // ex: 0:left2right 1:bottom2top 2:...
private:
void mouserPress() {
state = 0; // possible. You don't know yet is the mouse is going to swipe, simple click, long press, etc.
// save some values so you can calculate the direction of the swipe later
target.gestureHandle(this);
};
void mouserMove() {
if (state == 0) {
state = 1; // it was possible now you know the swipe began!
direction = ... // calculate the swipe direction here
} else if (state == 1 || state == 2) {// state is began or changed
state = 2; // changed ... which means is still mouse dragging
// probably you want to make more checks here like you are still swiping in the same direction you started, maybe velocity thresholds, if any of your conditions are not met you should cancel the gesture recognizer by setting its state to 4
}
target.gestureHandler(this);
};
void mouserRelease() {
if (state == 2) { // is swipping
state = 3; // swipe ended
} else {
state = 4; // it was not swiping so simple cancel the tracking
}
target.gestureHandler(this);
};
void mouserWheel() {
// if this method is called then this is definitely not a swipe right?
state = 4; // cancelled
target.gestureHandler(this);
}
イベントが発生しているときに上記のメソッドが呼び出され、必要に応じてターゲットを呼び出す必要があることを確認してください。
これは、ターゲットが私にどのように見えるかです。
class Target {
...
void gestureHandler(Recognizer *r) {
if (r->state == 2) {
// Is swipping: move the opengl camera using some parameter your recognizer class brings
} else if (r->state == 3) {
// ended: stop moving the opengl camera
} else if (r->state == 4) {
// Cancelled, maybe restore camera to original position?
}
}
UIGestureRecognizerの実装は非常に優れており、同じレコグナイザーと複数のレコグナイザーの複数のターゲット/メソッドを同じビューに登録できます。UIGestureRecognizersには、他のジェスチャ認識機能に関する情報を取得するために使用されるデリゲートオブジェクトがあります。たとえば、2つのジェスチャを同時に検出できる場合や、一方が検出されたらすぐに失敗する必要がある場合などです。
一部のジェスチャレコグナイザは他のジェスチャよりも多くのオーバーライドを必要としますが、これの大きな利点は、出力が同じであるということです。つまり、現在の状態(およびその他の情報)を通知するハンドラメソッドです。
一見の価値があると思います
それが役に立てば幸い :)