2017-11-23 6 views
0

私は、motionManagerのデバイスモーションコールのgravityYパラメータに基づいたレベルのiPhoneアプリケーションを持っています。私は、携帯電話のピッチにレベルを固定しました。私は、電話機がx軸を介して平面(地面に対して平坦)に対して上昇または下降しているかどうかをユーザーに示したいと思っています。関連性がありません。これを行うには、レベル(バー)に沿ってインジケータ(レベルが外れている場合は赤色)をスライドさせるようにアプリをプログラミングしました。最大移動量はレベルの各端です。Swift 3デバイスの動きの重力

レベルは素晴らしいです...ユーザーが電話をロックして後ろのポケットに入れるまで、正しい値が表示されます。この段階では、レベルインジケータがレベルの一端(ポケットの中で上昇している電話の終わり)に移動し、電話が引き出されてロックが解除されると、アプリはすぐにレベルを復元しません。私はレベルを復元する手動関数呼び出しを行う場合でも、レベルのアウト。約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))" 
})} 
} 
} 

はまだまったく同じように動作

答えて

0

OKを私はこれを試行錯誤で見つけました。まず、次のように私は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に通知し、機能を実行します。すぐに問題が修正されました。

関連する問題