2010年2月25日木曜日

iPhoneアプリで簡単にシェイクジェスチャーを検知するには?

iPhoneでシェイクジェスチャーを検知出来ることは知っていたが、多分加速度センサーの計測値をハイパスフィルターしてベクトル計算してあーじゃこーじゃするのだろうと思っていた。

しかし、ドキュメントを見ていたら、iPhone 3.0以降では「モーションイベント」というほぼシェイクジェスチャー検知専用とも言えるイベントハンドラーがあるらしいじゃないですか。
iPhone アプリケーションプログラミングガイド」 PDF P96

UIViewなどUIResponderのサブクラスにmotionBegan()とかmotionEnded()とかmotionCancelled()とか書けば検知出来るらしい事を書いてあったので実際に書いてみたら、これが動作しない(^^);

オカシイと思ってさらに調べると、英語版のドキュメントの方にちょっとしたマジナイが必要だという事が書いてあるのを見つけた。
iPhone Application Programing Guide

モーションイベントを受け取りたいクラスは、ファーストレスポンダーにならなければならないそうだ。そこでメインのビューコントローラーにこのコードを加えた。

- (BOOL)canBecomeFirstResponder {
  NSLog(@"canBecomeFirstResponder()");
  return YES;
}

- (void)viewDidAppear:(BOOL)animated {
  NSLog(@"viewDidAppear()");
  [self becomeFirstResponder];
}

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
  NSLog(@"motionBegan()");
}

- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {
  NSLog(@"motionCancelled()");
}

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
  NSLog(@"motionEnded()");
}

かなり簡単にモーションジェスチャーの検知ができることがわかったが、反応はイマイチか?

motionBegan()は大体OKだが、シェイクのしかたによってはmotionEnded()が呼ばれない場合もあるし、motionCancelled()はたまに呼ばれるのだが、イマイチどういった場合に呼ばれるのかわからない。

motionBegan()は実用範囲だと思う。有効に使えばトグルボタンを押す代わりなどに使えるだろう。


しかし、日本語ドキュメントは英語のドキュメントに比べると足りない部分があるようだ。最終的には、やはり英語ドキュメントをあたらないとダメか・・・