我使用CMMotionManager来获取设备的姿态,并遇到一个特殊的问题,它在第一次启动时完美地工作,但在停止和启动后,它给出了两倍的偏转数。
我使用startDeviceMotionUpdates(using: .xTrueNorthZVertical)
启动它,并检查SceneKit场景的渲染循环中的偏航值。如果我把手机平放在桌子上并旋转90°,它会显示偏航方向的90°变化。完美。
如果我使用stopDeviceMotionUpdates()
停止它,再次启动它,并执行相同的90°旋转,我期望看到相同的90°变化。但相反,它显示了180°的旋转!
这似乎只发生在第一次用(using:)
语法开始时。我在安装iOS 10.0.2的iPhone 5上使用xCode 8.0进行测试。
要重新创建,使用"Game"模板创建一个新项目,并用以下代码替换GameViewController.swift中的代码:
import UIKit
import SceneKit
import CoreMotion
class GameViewController: UIViewController, SCNSceneRendererDelegate {
static let motionManager = CMMotionManager()
var scnView: SCNView!
var scnScene: SCNScene!
override func viewDidLoad() {
super.viewDidLoad()
scnView = self.view as! SCNView
scnView.delegate = self
scnScene = SCNScene()
scnView.scene = scnScene
scnView.isPlaying = true
GameViewController.motionManager.startDeviceMotionUpdates(using: .xTrueNorthZVertical)
// stop and start it again to cause doubling
GameViewController.motionManager.stopDeviceMotionUpdates()
GameViewController.motionManager.startDeviceMotionUpdates(using: .xTrueNorthZVertical)
}
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
if let motion = GameViewController.motionManager.deviceMotion {
print(Int(motion.attitude.yaw * 180/M_PI))
}
}
}
此代码启动cmmotionmanager,然后立即停止它并再次启动它。将手机旋转90°,你会看到它显示180°的偏航。显然,这不是一个实际的例子,只是一个简化的版本,显示了这个问题。在我的实际用例中,当我正在使用的SceneKit视图被驳回时,我停止CMMotionManager,并在打开另一个SceneKit视图时重新启动它。
现在我的解决办法是永远不要停止CMMotionManager一旦它启动。它是有效的,但是文档特别指出"当你不再希望应用程序处理设备运动更新时,你必须调用stopDeviceMotionUpdates()",所以这似乎不是一个很好的解决方案。
为什么CMMotionManager在停止和启动后给出错误的值,我能做些什么来修复它?
CMMotion manager给出了我们调用start函数时的角度。
如果你需要更新,那么你不应该停止更新。当不需要关联前一个位置时停止
此行为在安装iOS 10.1后消失,因此可能是一个已修复的错误。