2016-10-07 5 views
0

Я использую CMMotionManager, чтобы получить отношение к устройству, и столкнулся с особой проблемой, когда он работает отлично при первом запуске, но после остановки и запуска он дает удвоенные числа для рыскания.Почему CMMotionManager сообщает о некорректном рыскании после остановки и перезапуска?

Я начинаю с startDeviceMotionUpdates(using: .xTrueNorthZVertical) и проверяет значения рыскания в цикле рендеринга сцены SceneKit. Если я положил телефон на стол и повернул его на 90 °, он показал изменение на 90 ° в рыскании. Отлично.

Если я остановлю его, используя stopDeviceMotionUpdates(), запустите его снова и выполните то же вращение на 90 °, я ожидаю увидеть такое же изменение на 90 °. Но вместо этого он показывает 180 ° вращения!

Это похоже на то, что это происходит при первом запуске с синтаксисом (using:). Я тестирую его на iPhone 5 с iOS 10.0.2, используя xCode 8.0.

Чтобы воссоздать, создать новый проект с помощью «Игра» шаблон и заменить код в 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)) 
     } 
    } 
} 

Этот код начинается CMMotionManger, то немедленно останавливает его и запускает его снова. Поверните телефон на 90 °, и вы увидите, что он показывает 180 ° рыскания. Очевидно, что это не практический пример, просто упрощенная версия, которая показывает проблему. В моем фактическом использовании я останавливаю CMMotionManager, когда представление SceneKit, в котором я его использую, отклоняется и перезапускает его, когда открывается другое представление SceneKit.

На данный момент мое обходное решение - никогда не останавливать CMMotionManager после его запуска. Он работает, но в документации конкретно говорится: «You должен call stopDeviceMotionUpdates(), когда вы больше не хотите, чтобы ваше приложение обрабатывало обновления движений устройства». Это не похоже на отличное решение.

Почему CMMotionManager дает неправильные значения после остановки и запуска, и что я могу сделать, чтобы исправить это?

ответ

0

Это поведение исчезло после установки iOS 10.1, поэтому предположительно это была исправленная ошибка.

0

CMMotion manager дает поворот угла, когда мы вызываем функцию запуска.

Если вам нужны обновления, вы не должны останавливать обновления. остановите его, когда нет необходимости связывать предыдущую позицию.

+0

В моем фактическом прецеденте я останавливаю CMMotionManager, когда вид SceneKit, в котором я его использую, отклоняется, а затем перезапускает его, если/когда открывается другое представление SceneKit. Пример в моем вопросе - это лишь минимальный пример, который показывает проблему. – Robert