在Swift中查找iPhone的指南针方向

12
我正在尝试制作一个类似于指南针的应用程序,但是有明显的区别,不过这些并不重要。我需要知道的是:如何让iPhone给我提供指南针方向(即北方为0度),无论手机的朝向如何(例如,如果手机平放在桌子上或者竖直握在手中,只要它指向相同的方向,就会给出相同的读数)。
简而言之,如何获取iPhone绕y轴旋转的角度,每秒钟更新一次左右。
3个回答

26

导入CoreLocation

class ViewController: UIViewController ,CLLocationManagerDelegate {

    var lm:CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()

        lm = CLLocationManager()
        lm.delegate = self

        lm.startUpdatingHeading()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func locationManager(manager: CLLocationManager!, didUpdateHeading newHeading: CLHeading!) {
        println(newHeading.magneticHeading)
    }
}

您可以从https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLHeading_Class/获取更多信息。


我已经在模拟器和设备上都尝试过了,但是无法显示任何方向值。我将其绑定到一个标签上,当我在室外走动时应该更新。有什么想法吗? - Ethan Parker
1
回答不错,但我想不出实现 didReceiveMemoryWarning() 并仅调用 super 的理由 - 我的意思是,那是默认行为。 - Wil Shipley

10

Swift 3:

import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

       // Azimuth
        if (CLLocationManager.headingAvailable()) {
            locationManager.headingFilter = 1
            locationManager.startUpdatingHeading()
            locationManager.delegate = self
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateHeading heading: CLHeading) {
        print (heading.magneticHeading)
    }

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

我在我的应用程序中完全按照您在此处展示的代码进行了编写,但是在打开位置路径的模拟器中,我从未得到任何标题的输出。 - David Findlay
2
模拟器不支持磁头方向,请在真实设备上尝试。 - Sébastien REMY

5

Swift 3.0

    import UIKit
    import CoreLocation

    class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var compass: UIImageView!
    @IBOutlet weak var angleLabel: UILabel!
    @IBOutlet weak var geographicalDirectionLabel: UILabel!

    var locationManager = CLLocationManager()

    override func viewDidLoad() {

        super.viewDidLoad()


        locationManager.delegate = self

        // Start location services to get the true heading.
        locationManager.distanceFilter = 1000
        locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
        locationManager.startUpdatingLocation()

        //Start heading updating.
        if CLLocationManager.headingAvailable() {
            locationManager.headingFilter = 5
            locationManager.startUpdatingHeading()
        }




    }

    func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {

        if newHeading.headingAccuracy < 0 {
            return
        }

        // Get the heading(direction)
        let heading: CLLocationDirection = ((newHeading.trueHeading > 0) ?
            newHeading.trueHeading : newHeading.magneticHeading);
        UIView.animate(withDuration: 0.5) {
            let angle = CGFloat(heading).toRadians // convert from degrees to radians
            self.compass.transform = CGAffineTransform(rotationAngle: angle) // rotate the picture
        }
        print(heading)
        angleLabel.text = String(format: "%0.2f", heading)

       var strDirection = String()
        if(heading > 23 && heading <= 67){
            strDirection = "North East";
        } else if(heading > 68 && heading <= 112){
            strDirection = "East";
        } else if(heading > 113 && heading <= 167){
            strDirection = "South East";
        } else if(heading > 168 && heading <= 202){
            strDirection = "South";
        } else if(heading > 203 && heading <= 247){
            strDirection = "South West";
        } else if(heading > 248 && heading <= 293){
            strDirection = "West";
        } else if(heading > 294 && heading <= 337){
            strDirection = "North West";
        } else if(heading >= 338 || heading <= 22){
            strDirection = "North";
        }

        geographicalDirectionLabel.text = strDirection
    }
  }

谢谢您的回答,trueHeading是否提供与北方相关的真实值? - user924

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接