更正当前 UIInterfaceOrientation 的 CMMotionManager 偏航

Correct CMMotionManager yaw for current UIInterfaceOrientation

我正在使用 CMMotionManger 通过以下代码获取偏航读数。

不管 UIInterfaceOrientation,如果向右偏转 90 度,我试图获得负 1.5708 rad 的读数,如果设备向左偏转 90 度,则为正 1.5708 rad(不关心极性,因为它可以根据需要反转) .

当设备处于纵向时,我可以让它做我想做的事。以弧度为单位,当设备向右偏转 90 度时,它给了我大约 -1.5708,当向左旋转时,它给了我大约 1.5708 弧度。

但是当设备处于纵向颠倒方向时,当偏航向右旋转时,它从 -2.4 左右开始下降到 -3.14 左右,然后跳到 ~3.14 下降到 2.6。我怎样才能使它在 0 到 -1.5708 rad 之间平滑连续?

我还需要校正左右横向。

if motionManager == nil {
    motionManager = CMMotionManager()
}

let updateInterval: NSTimeInterval = 1 / 24.0 //24hz

if (motionManager!.accelerometerAvailable) {
    motionManager!.accelerometerUpdateInterval = updateInterval

    motionManager!.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: { (motion:CMDeviceMotion?, error: NSError?) -> Void in

        print("\(motion!.attitude.yaw)")

        switch (TDTDeviceUtilites.interfaceOrientation()) {
            case UIInterfaceOrientation.Portrait:
                // No correction needed
                break;

            case UIInterfaceOrientation.PortraitUpsideDown:
                //need to apply correction
                break;

            case UIInterfaceOrientation.LandscapeRight:
                //need to apply correction
                break;

            case UIInterfaceOrientation.LandscapeLeft:
                //need to apply correction
                break;
        }
    })
}

事实证明,CMMotionManager 将自身定位为当前的 UIInterfaceOrientation。因此,最简单的解决方案是在设备旋转时停止并重新启动 CMMotionManager。 (希望我早知道这一点会让我少受很多挫折!)例如:

public override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
     stopMotionUpdates()
     motionManager = nil
     startMotionUpdates()
}

func stopMotionUpdates() {              
    motionManager?.stopMagnetometerUpdates()
    motionManager?.stopDeviceMotionUpdates()
    motionManager?.stopAccelerometerUpdates()
}

func startMotionUpdates() { 
    //Start motion updates is the code in the question above
}