- マルチタッチイベント
 - 画面にタッチされたなど
 - モーションイベント
 - デバイスが傾けられたなど
 - リモートコントロールイベント
 - 音声を上げるボタンが押されたなど
 
マルチタッチイベントとは
ユーザが画面タッチすると、マルチタッチイベントが発生して、「指が画面に触れている」「指が動いた」「指が画面から離された」「何本の指で同時にタッチしているか」ということを認識できるようになります。通常、アプリを作成する上で必ず制御しなければならないイベントとなっています。iOS3.2以前では、タップされた・スワイプされたなどの情報は
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
を使って自前で挙動を定義しなければなりませんでした。しかし、マルチタッチイベントを自分で処理するのは面倒ですし、メンテナンスしづらくなるためバグも発生しやすくなります。そこで、iOS3.2から用意されている「Gesture Recognizer」クラスを利用します。Gesture Recognizerクラスのおかげで、簡単にマルチタッチイベントを扱えるようになりました。用意されているジェスチャーの種類は限られていますが、頻発するものであるために十分利便性の高いものばかりです。
もし不十分な場合は、自前でGesture Recognizerのサブクラスを作成することになります。
まず今回は、用意されている Gesture Recognizer と、そのサブクラスのサンプルです。
Gesture Recognizerの詳細【iOS 3.2以降】
認識可能なジェスチャーは以下のものが用意されています。| ジェスチャー | UIKitのクラス | 
|---|---|
| タップ(タップ数は任意) | UITapGestureRecognizer | 
| ピンチインとピンチアウト(ビューのズーム拡大縮小用) | UIPinchGestureRecognizer | 
| パニング(ドラッグ) | UIPanGestureRecognizer | 
| スワイプ(任意の方向に対応) | UISwipeGestureRecognizer | 
| 回転(互いに反対の方向への指の移動) | UIRotationGestureRecognizer | 
| 長押し(「タッチアンドホールド」とも呼ばれる) | UILongPressGestureRecognizer | 
いずれも、ジェスチャーを認識したら、セレクタとして登録してあるメソッドを呼び出してもらうというものです。
例えば、1本指でのシングルタップを認識したい場合は、以下のような具合です。
/* ジェスチャーの登録*/
- (void)addTapGestureRecognizer
{
    UITapGestureRecognizer *singleFingerSingleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerSingleTap:)];
    [self.view addGestureRecognizer:singleFingerSingleTap];
    [singleFingerSingleTap release];
}
/* ジェスチャーが認識された場合に実行される処理 */
- (void)handleSingleFingerSingleTap:(UITapGestureRecognizer *)recognizer
{
    // タップされた場合の処理
}
そして、1本指でのタップの場合は選択し、ダブルタップの場合は拡大したい等の場合は以下のようになります。
- (void)addTapGestureRecognizer
{
    // シングルタップ
    UITapGestureRecognizer *singleFingerSingleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerSingleTap:)];
    // ダブルタップ
    UITapGestureRecognizer *singleFingerDoubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerDoubleTap:)];
    [singleFingerDoubleTap setNumberOfTapsRequired:2];
    // ダブルタップの失敗時のみシングルタップを実行する (シングルタップとダブルタップが同時に認識されてしまうのを回避する)
    [singleFingerSingleTap requireGestureRecognizerToFail:singleFingerDoubleTap];
    // ビューへの登録とリリース
    [self.allGesturesView addGestureRecognizer:singleFingerSingleTap];
    [singleFingerSingleTap release];
    [self.allGesturesView addGestureRecognizer:singleFingerDoubleTap];
    [singleFingerDoubleTap release];
}
ここでは「requireGestureRecognizerToFailメソッド」を書いていますが、単純にシングルタップとダブルタップのジェスチャーを登録しただけでは、シングルタップとダブルタップの両方が同時に認識されてしまいます。
![]()  | 
| 単純にUIGestureRecognizerを両方を定義した場合 | 
![]()  | 
| requireGestureRecognizerToFailメソッドでの制御 | 
サンプル
ソースコードはGitHubに公開してあります。iOS-SampleCodes/GestureRecognizers - GitHub
今回はUIGestureRecognizerのみを使ったサンプルのため非常に簡単ですが、以下、サンプル画像です。
起動すると以下の画面が表示されます。これは3つのビューに分かれています。
- 全てのUIGestureRecognizerを追加したビュー
 - UIPanGestureRecognizerのみを追加したビュー
 - UISwipeGestureRecognizerのみを追加したビュー
 
PanとSwipeだけを分けたのは単純に、「1.」のビューで競合してしまい、Panが認識されないからです。全てのジェスチャーを同じビューに追加することはほぼ無いでしょうが、Panは認識されなくなってしまいます。同時に認識させたい場合は「UIGestureRecognizerDelegateプロトコル」の「gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:」を実装することで回避できるのですが、単純にするためビューを分けています。
![]()  | 
| 3つのビューにそれぞれのGestureRecognizerを追加してある | 
| 「1.」のビューでPinchGestureを実行 | 「3.」のビューでSwipeGestureを実行 | 







0 コメント:
コメントを投稿