【问题标题】:Swift 3 device motion gravitySwift 3 设备运动重力
【发布时间】:2017-11-23 18:56:47
【问题描述】:

我有一个 iPhone 应用程序,其中有一个级别,它基于对 motionmanager 的设备运动调用的重力 Y 参数。我已将水平固定到手机的俯仰,因为我希望通过其 x 轴向用户显示手机相对于平面(平地)是升高还是下降......并排或旋转不相关。为此,我对应用程序进行了编程,使其沿着水平(条形)滑动指示器(超出水平时为红色)......它的最大行程是水平的每一端。

该级别运行良好...并显示正确的值,直到用户锁定手机并将其放在他或她的后袋中。而在这个阶段,水平指示器移动到水平的一端(手机在口袋中升高的一端),当手机被拉出并解锁时,应用程序不会立即恢复水平 - 它仍然存在超出级别,即使我执行手动函数调用来恢复级别。大约 5 分钟后,水平似乎恢复了。

代码如下:

func getElevation () {

    //now get the device orientation - want the gravity value
    if self.motionManager.isDeviceMotionAvailable {

        self.motionManager.deviceMotionUpdateInterval = 0.05

        self.motionManager.startDeviceMotionUpdates(
            to: OperationQueue.current!, withHandler: {
                deviceMotion, error -> Void in

                var gravityValueY:Double = 0

                if(error == nil) {
                    let gravityData = self.motionManager.deviceMotion
                    let gravityValueYRad = (gravityData!.gravity.y)
                    gravityValueY = round(180/(.pi) * (gravityValueYRad))

                    self.Angle.text = "\(String(round(gravityValueY)))"
                }
                else {
                    //handle the error
                    self.Angle.text = "0"
                    gravityValueY = 0
                }
                var elevationY = gravityValueY
                //limit movement of bubble
                if elevationY > 45 {
                    elevationY = 45
                }
                else if elevationY < -45 {
                    elevationY = -45
                }

                let outofLevel: UIImage? = #imageLiteral(resourceName: "levelBubble-1")
                let alignLevel: UIImage? = #imageLiteral(resourceName: "levelBubbleGR-1")

                let highElevation:Double = 1.75
                let lowElevation:Double = -1.75

                if highElevation < elevationY {
                    self.bubble.image = outofLevel
                }
                else if elevationY < lowElevation {
                    self.bubble.image = outofLevel
                }
                else {
                    self.bubble.image = alignLevel
                }
                // Move the bubble on the level
                if let bubble = self.bubble {
                    UIView.animate(withDuration: 1.5, animations: { () -> Void in
                        bubble.transform = CGAffineTransform(translationX: 0, y: CGFloat(elevationY))
                    })
                }
        })
    }
}

我希望级别几乎立即恢复(在 2-3 秒内)。我无法强制校准或更新。这是我的第一篇文章....帮助表示赞赏。

编辑 - 我尝试使用以下代码设置一个没有任何动画的单独应用程序:

//

import UIKit
import CoreMotion

class ViewController: UIViewController {

let motionManager = CMMotionManager()

@IBOutlet weak var angle: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func startLevel(_ sender: Any) {
    startLevel()
}

func startLevel() {
//now get the device orientation - want the gravity value
if self.motionManager.isDeviceMotionAvailable {

self.motionManager.deviceMotionUpdateInterval = 0.1
self.motionManager.startDeviceMotionUpdates(
to: OperationQueue.current!, withHandler: {
deviceMotion, error -> Void in

var gravityValueY:Double = 0

if(error == nil) {
    let gravityData = self.motionManager.deviceMotion
    let gravityValueYRad = (gravityData!.gravity.y)
    gravityValueY = round(180/(.pi) * (gravityValueYRad))
    }
else {
    //handle the error
     gravityValueY = 0
    }
self.angle.text = "(\(gravityValueY))"
})}
}
}

仍然表现完全相同....

【问题讨论】:

    标签: ios iphone swift gravity


    【解决方案1】:

    好的....所以我通过反复试验发现了这一点。首先,我构建了一个 stopGravity 函数如下:

        func stopGravity () {
    if self.motionManager.isDeviceMotionAvailable {
        self.motionManager.stopDeviceMotionUpdates()
        }
    }
    

    我发现,如果我调用该函数(例如通过移动到新视图,然后在返回原始视图时重新开始更新),则级别始终设置正确。锁定设备或单击主页按钮时,我需要调用相同的函数,然后在重新加载或返回视图时重新启动重力功能。

    为此,我在 viewDidLoad() 中插入了以下内容...

            NotificationCenter.default.addObserver(self, selector: #selector(stopGravity), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(stopGravity), name: NSNotification.Name.UIApplicationWillTerminate, object: nil)
    

    这会通知 AppDelegate 并运行该函数。这立即解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-06
      • 1970-01-01
      • 2018-08-19
      • 2017-11-16
      • 2017-10-13
      • 1970-01-01
      相关资源
      最近更新 更多