motionBegan, motionEnded を使う
一番手っ取り早いのが UIResponder の motionBegan/motionEneded をオーバーライドする方法です。
まずは canBecomeFirstResponder をオーバーライドして motionBegan/motionEneded が呼ばれるようにします。
override func canBecomeFirstResponder() -> Bool {
return true
}
motionBegan/motionEneded を実装して行いたい処理を書きます。
override func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent) {
if event.type == UIEventType.Motion && event.subtype == UIEventSubtype.MotionShake {
// シェイク動作始まり時の処理
}
}
override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent) {
if event.type == UIEventType.Motion && event.subtype == UIEventSubtype.MotionShake {
// シェイク動作終了時の処理
}
}
利点
実装が簡単。
欠点
シェイク動作開始・終了時しか検知できません。シェイクした回数をカウントしたい、などの場合はこの方法は使えません。
CMMotionManager を使う
シェイクした回数をカウントする場合は加速度センサーを使います。
- CoreMotion.framework を追加
- CMMotionManager を生成
- 計測間隔を指定(ここでは 0.2 秒)
- x,y,z 座標の加速度を取得
- 直前の加速度と向きが変わっていればシェイクしたと判断する
let motionManager = CMMotionManager()
var x = 0
var y = 0
var z = 0
override func viewDidLoad() {
super.viewDidLoad()
self.motionManager.accelerometerUpdateInterval = 0.2
self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {
(data, error) in
dispatch_async(dispatch_get_main_queue()) {
self.updateAccelerationData(data.acceleration)
}
}
}
func updateAccelerationData(data: CMAcceleration) {
Logger.log("x = \(Int(data.x)), y = \(Int(data.y)), z = \(Int(data.z))")
var isShaken = self.x != Int(data.x) || self.y != Int(data.y) || self.z != Int(data.z)
if isShaken {
// シェイクされたときの処理
}
self.x = Int(data.x)
self.y = Int(data.y)
self.z = Int(data.z)
}
利点
細かい情報まで取れる。
シェイクしたと判断する基準(計測間隔やどの軸の加速度に着目するか)を用途に合わせて変えられる。
欠点
実装がちょっとめんどくさい。