iOS端末の現在の向きを取得するためのメモです。現在の向きと言っても縦横などの簡単な回転方向ではなく、どの向きにどの程度傾いているかを角度で取得します。
サンプルのプロジェクトをgithubにpushしときました(Xcode5+iOS7)
https://github.com/yimajo/DeviceMotionAttitudeDemo
サンプルの画面はこんな感じ
モーションデータ取得イベント
モーションデータの取得タイミングは自前のプル型と自動のプッシュ型があります。それぞれの説明は次のとおりです。
- プル型
- 自前で取得しに行くタイミングを設定します。例えばゲームアプリでループの画面更新処理を作った場合などに無駄がないのではないかと思います。センサーに対してpullするからプル型と覚えるとスッキリします。
- プッシュ型
- 自動的に取得できます。センサーからpushされるからプッシュだと覚えるとスッキリします。
デバイスの回転方向
デバイスの向きはオイラー角としてデバイスの3次元空間上の姿勢から取得できます。軸はPitch、Roll、Yawで、それぞれ次の図ではX,Y,Zとなります
コード
イベントハンドラの部分的なコードのみ抜粋するとこんな感じ。エラー処理はいれてません。
- (void)attiude
{
if (self.motionManager.deviceMotionAvailable) {
__weak MasterViewController *viewController = self;
// 向きの更新通知を開始する
[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue]
withHandler:^(CMDeviceMotion *motion, NSError *error)
{
viewController.pitchLabel.text
= [NSString stringWithFormat:@"%f", motion.attitude.pitch * 180 / M_PI];
viewController.rollLabel.text
= [NSString stringWithFormat:@"%f", motion.attitude.roll * 180 / M_PI];
viewController.yawLabel.text
= [NSString stringWithFormat:@"%f", motion.attitude.yaw * 180 / M_PI];
}];
}
}
重要なのはCMMotionManagerのメソッドで取得できるCMDeviceMotionのプロパティCMAttiudeが現在の回転角度を保持している点です。CMGyroDataを取得してしまうとジャイロデータにそのままアクセスしてしまい、回転した方向とその速度が都度取得できます(それが必要になることもあるんでしょうが今回の趣旨とはズレていました)。
参考
Apple公式 「iOSイベント処理ガイド」PDF
https://developer.apple.com/jp/devcenter/ios/library/documentation/EventHandlingiPhoneOS.pdf