iPhone OS3.0 から本体をシェイク(振る)すると Undo できるようになりました。OS3.0 以前では加速度センサをチェックすることで、シェイク動作をチェックすることができましたが、OS3.0 からは UIRespoer の motionEnded:withEvent: でシェイク動作を取得することができます。

UIEvent に以下のプロパティがあります。

  • @property(readonly) UIEventType type;
  • @property(readonly) UIEventSubtype subtype;
  • UIEventTypeMotion
  • UIEventSubtypeMotionShake

UIWindow でシェイクを感知

一番簡単にやるには、UIWindow のサブクラスを作成して、そこでチェックする方法です。

@implementation ShakeWindow
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
  if (event.type == UIEventTypeMotion &&
      motion == UIEventSubtypeMotionShake) {
    NSLog(@"shake!");
  }
}
@end

UIWindow クラスを使用している箇所を ShakeWindow クラスに変更すれば、シェイク動作を取得できます。
注意点は IB を使用しているときは AppDelegate だけでなく、MainWindow.xib の方も修正する必要があります。

UIView でシェイクを感知

UIWindow でシェイクを感知するとアプリケーション全体で常にシェイク動作を感知してしまいます。そこで必要なときにのみ感知するように、特定の UIView でのみ感知するようにしてみます。

まず、シェイク動作をチェックしたい UIView のサブクラス ShakeView を作成します。シェイク動作を検知するためにはファーストレスポンダにならないといけないので、canBecomeFirstResonder をオーバライドして YES を返します。

@implementation ShakeView
- (BOOL)canBecomeFirstResponder {
	return YES;
}
@end

次に、UIViewController で ShakeView を addView して、motionEnded:withEvent: でシェイクを検知します。

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
  if (event.type == UIEventTypeMotion &&
      motion == UIEventSubtypeMotionShake) {
    NSLog(@"shake!");
  }
}
- (void)viewDidLoad {
  [super viewDidLoad];

  ShakeView* shakeView = [[ShakeView alloc] init];
  shakeView.frame = self.view.bounds;
  [shakeView becomeFirstResponder];
  [self.view addSubview:shakeView];
  [shakeView release];
}

関連する投稿