iPhoneのシェイクジェスチャー(振る動作)を検知する方法を説明します。
実装方法
まずは、シェイクジェスチャーを検知したいクラス*1で canBecomeFirstResponder
をオーバーライドして YES
を返します。これは、シェイク動作を検知するためにファーストレスポンダになる必要があるためです。
- (BOOL)canBecomeFirstResponder { return YES; }
Swift:
override func canBecomeFirstResponder() -> Bool { return true }
これで、シェイクジェスチャーを受け取る準備が整いました。
この状態でiPhoneを振ると、次のメソッドが呼ばれます。
// シェイク開始 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) { NSLog(@"Motion began"); } } // シェイク完了 - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) { NSLog(@"Motion ended"); } } // シェイクがキャンセルされた - (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) { NSLog(@"Motion cancelled"); } }
Swift:
override func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent?) { if event?.type == UIEventType.Motion && event?.subtype == UIEventSubtype.MotionShake { // Motion began } } override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent?) { if event?.type == UIEventType.Motion && event?.subtype == UIEventSubtype.MotionShake { // Motion ended } } override func motionCancelled(motion: UIEventSubtype, withEvent event: UIEvent?) { if event?.type == UIEventType.Motion && event?.subtype == UIEventSubtype.MotionShake { // Motion cancelled } }
引数として UIEvent
が渡されるので、そのプロパティである UIEventType
と UIEventSubtype
を見てシェイクジェスチャーであるかどうかの判定をしています。
通常は motionBegan
→ motionEnded
の順に呼ばれます。
iPhoneを軽く振っただけでは motionBegan
しか呼ばれず、一定時間放置すると motionCancelled
が呼ばれるようです。
サンプルコード
- https://github.com/koogawa/iSensor/blob/master/iSensor/ShareViewController.m
- https://github.com/koogawa/iSensorSwift/blob/master/iSensorSwift/Controller/ShakeViewController.swift
注意点
- iOS 3 以降で使用できます
応用できそうなアプリ
- シェイクすることで音が鳴る楽器アプリ
- iPhoneを振ることで何かを競うゲーム
- シェイク動作によるリセット処理
参考にさせて頂いたリンク
*1:UIViewControllerなど、UIResponderクラスを継承している必要があります