Search code examples
iosswift2core-motion

Swift CMMotion - Displaying the angle of the phone


So I've been hunting around trying to learn about Core Motion and I'm struggling to find anything that brings it down to a beginners level. It seems there isn't too much out there compared to other topics.

My Aim: to make a UILabel display the angle the phone is on (I believe about the z-axis), 0 degrees being when the phone is landscape.

I saw this article from NSHipster that i think was sending me in the right ballpark, so i tried to recreate the code that is seen in the .gif in this article. It keeps the UIImageView vertical as the phone tilts....no luck. I just don't understand the bigger picture of how all those code snippets work together, I suppose because this is my first time playing the the Core Motion.

My question:

1) Could anyone recreate that moving imageView seen in that link for me so i can study how it all works together (preferably the whole viewController.swift file).

Or even better

2) Put some code together that would display what angle the phone is sitting on.

Let me know if I can be more specific. Many Thanks!

UPDATE: Well I surprised myself and managed to work it out, then came here to post it and TJ Shae just posted the answer too haha... took a lot of messing around but I'm on my way now.

    import UIKit
    import CoreMotion

    class AngleGaugeViewController: UIViewController {

@IBOutlet weak var rotX: UILabel!
@IBOutlet weak var rotY: UILabel!
@IBOutlet weak var rotZ: UILabel!
@IBOutlet weak var theAngle: UILabel!

@IBOutlet weak var imageView: UIImageView!


let manager = CMMotionManager()

override func viewDidLoad() {
    super.viewDidLoad()


    manager.gyroUpdateInterval = 0.1
    manager.accelerometerUpdateInterval = 0.1

    manager.startGyroUpdates()
    manager.startAccelerometerUpdates()


    let queue = NSOperationQueue.mainQueue
    manager.startGyroUpdatesToQueue(queue()) {
        (data, error) in
        // ...
    }



    if manager.deviceMotionAvailable {
        manager.deviceMotionUpdateInterval = 0.01
        manager.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue()) {
            [weak self] data, error in

            let rotation = atan2(data!.gravity.x, data!.gravity.y) - M_PI
            self?.imageView.transform = CGAffineTransformMakeRotation(CGFloat(rotation))
        }
    }




}

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

}


Solution

  • Well, the NSHipster code worked perfectly for me first time :] Here is the UIViewController code:

    import UIKit
    import CoreMotion
    
    class ViewController: UIViewController {
    
    @IBOutlet weak var imgView: UIImageView!
    
    let manager = CMMotionManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        if manager.deviceMotionAvailable {
            manager.deviceMotionUpdateInterval = 0.01
            manager.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue()) {
                (data, error) in
                if let data = data {
                    let rotation = atan2(data.gravity.x, data.gravity.y) - M_PI
                    self.imgView.transform = CGAffineTransformMakeRotation(CGFloat(rotation))
                }
            }
        }
    }
    
    }