【问题标题】:Displaying the speed the device is travelling at using CLLocationSpeed [closed]使用 CLLocationSpeed 显示设备的行驶速度
【发布时间】:2016-08-23 19:28:20
【问题描述】:

我希望能够在一个简单的标签中显示设备的行驶速度。

我在苹果网站上找到了这个:

var speed: CLLocationSpeed { 获取 }

source

上面的代码将速度设置为m/s,因此我可以将其转换为每小时英里数等。

如何使用此代码显示速度?

我知道这是可以做到的,因为 snapchat 有它作为过滤器。

【问题讨论】:

  • 欢迎来到 StackOverflow!你有没有尝试过什么?通常,您访问该网站时会考虑特定的问题,而不是询问如何使用某些库。
  • 感谢您的快速回复!我尝试过使用当前位置的东西,并在互联网上搜索了似乎无休止的东西,但找不到任何关于显示速度的东西。

标签: swift core-location cllocationmanager


【解决方案1】:

更新到 Swift 4

这可能比您要寻找的要多,但希望对您有所帮助。

import UIKit
import MapKit
import CoreLocation

class TestViewController: UIViewController, CLLocationManagerDelegate {
    //MARK: Global Var's
    var locationManager: CLLocationManager = CLLocationManager()
    var switchSpeed = "KPH"
    var startLocation:CLLocation!
    var lastLocation: CLLocation!
    var traveledDistance:Double = 0
    var arrayMPH: [Double]! = []
    var arrayKPH: [Double]! = []

    //MARK: IBoutlets
    @IBOutlet weak var speedDisplay: UILabel!
    @IBOutlet weak var headingDisplay: UILabel!
    @IBOutlet weak var latDisplay: UILabel!
    @IBOutlet weak var lonDisplay: UILabel!
    @IBOutlet weak var distanceTraveled: UILabel!
    @IBOutlet weak var minSpeedLabel: UILabel!
    @IBOutlet weak var maxSpeedLabel: UILabel!
    @IBOutlet weak var avgSpeedLabel: UILabel!

    //MARK: Life Cycle
    override func viewDidLoad() {
        super.viewDidLoad()
        minSpeedLabel.text = "0"
        maxSpeedLabel.text = "0"
        // Ask for Authorisation from the User.
        self.locationManager.requestAlwaysAuthorization()

        // For use in foreground
        self.locationManager.requestWhenInUseAuthorization()
        if CLLocationManager.locationServicesEnabled() {
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.startUpdatingLocation()
        }
    }


    // 1 mile = 5280 feet
    // Meter to miles = m * 0.00062137
    // 1 meter = 3.28084 feet
    // 1 foot = 0.3048 meters
    // km = m / 1000
    // m = km * 1000
    // ft = m / 3.28084
    // 1 mile = 1609 meters
    //MARK: Location
    private func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations.last
        if (location!.horizontalAccuracy > 0) {
            updateLocationInfo(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude, speed: location!.speed, direction: location!.course)
        }
        if lastLocation != nil {
            traveledDistance += lastLocation.distance(from: locations.last!)
            if switchSpeed == "MPH" {
                if traveledDistance < 1609 {
                    let tdF = traveledDistance / 3.28084
                    distanceTraveled.text = (String(format: "%.1f Feet", tdF))
                } else if traveledDistance > 1609 {
                    let tdM = traveledDistance * 0.00062137
                    distanceTraveled.text = (String(format: "%.1f Miles", tdM))
                }
            }
            if switchSpeed == "KPH" {
                if traveledDistance < 1609 {
                    let tdMeter = traveledDistance
                    distanceTraveled.text = (String(format: "%.0f Meters", tdMeter))
                } else if traveledDistance > 1609 {
                    let tdKm = traveledDistance / 1000
                    distanceTraveled.text = (String(format: "%.1f Km", tdKm))
                }
            }
        }
        lastLocation = locations.last

    }

    func updateLocationInfo(latitude: CLLocationDegrees, longitude: CLLocationDegrees, speed: CLLocationSpeed, direction: CLLocationDirection) {
        let speedToMPH = (speed * 2.23694)
        let speedToKPH = (speed * 3.6)
        let val = ((direction / 22.5) + 0.5);
        var arr = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"];
        let dir = arr[Int(val.truncatingRemainder(dividingBy: 16))]
        //lonDisplay.text = coordinateString(latitude, longitude: longitude)

        lonDisplay.text = (String(format: "%.3f", longitude))
        latDisplay.text = (String(format: "%.3f", latitude))
        if switchSpeed == "MPH" {
            // Chekcing if speed is less than zero or a negitave number to display a zero
            if (speedToMPH > 0) {
                speedDisplay.text = (String(format: "%.0f mph", speedToMPH))
                arrayMPH.append(speedToMPH)
                let lowSpeed = arrayMPH.min()
                let highSpeed = arrayMPH.max()
                minSpeedLabel.text = (String(format: "%.0f mph", lowSpeed!))
                maxSpeedLabel.text = (String(format: "%.0f mph", highSpeed!))
                avgSpeed()
            } else {
                speedDisplay.text = "0 mph"
            }
        }

        if switchSpeed == "KPH" {
            // Checking if speed is less than zero
            if (speedToKPH > 0) {
                speedDisplay.text = (String(format: "%.0f km/h", speedToKPH))
                arrayKPH.append(speedToKPH)
                let lowSpeed = arrayKPH.min()
                let highSpeed = arrayKPH.max()
                minSpeedLabel.text = (String(format: "%.0f km/h", lowSpeed!))
                maxSpeedLabel.text = (String(format: "%.0f km/h", highSpeed!))
                avgSpeed()
                //                print("Low: \(lowSpeed!) - High: \(highSpeed!)")
            } else {
                speedDisplay.text = "0 km/h"
            }
        }

        // Shows the N - E - S W
        headingDisplay.text = "\(dir)"

    }

    func avgSpeed(){
        if switchSpeed == "MPH" {
            let speed:[Double] = arrayMPH
            let speedAvg = speed.reduce(0, +) / Double(speed.count)
            avgSpeedLabel.text = (String(format: "%.0f", speedAvg))
            //print( votesAvg )
        } else if switchSpeed == "KPH" {
            let speed:[Double] = arrayKPH
            let speedAvg = speed.reduce(0, +) / Double(speed.count)
            avgSpeedLabel.text = (String(format: "%.0f", speedAvg))
            //print( votesAvg
        }
    }

    //MARK: Buttons
    @IBOutlet weak var switchSpeedStatus: UIButton!
    @IBAction func speedSwtich(sender: UIButton) {
        if switchSpeed == "MPH" {
            switchSpeed = "KPH"
            switchSpeedStatus.setTitle("KPH", for: .normal)
        } else if switchSpeed == "KPH" {
            switchSpeed = "MPH"
            switchSpeedStatus.setTitle("MPH", for: .normal)
        }
    }

    @IBAction func restTripButton(sender: AnyObject) {
        arrayMPH = []
        arrayKPH = []
        traveledDistance = 0
        minSpeedLabel.text = "0"
        maxSpeedLabel.text = "0"
        headingDisplay.text = "None"
        speedDisplay.text = "0"
        distanceTraveled.text = "0"
        avgSpeedLabel.text = "0"
    }

    @IBAction func startTrip(sender: AnyObject) {
        locationManager.startUpdatingLocation()
    }

    @IBAction func endTrip(sender: AnyObject) {
        locationManager.stopUpdatingLocation()
    }
}

【讨论】:

    【解决方案2】:

    我在@Leo 的 SO 上找到了这个

    Swift: Exception while trying to print CLLocationSpeed "unexpectedly found nil while unwrapping an Optional value"

    import UIKit
    import CoreLocation
    class ViewController: UIViewController, CLLocationManagerDelegate {
    let locationManager = CLLocationManager()
    
    override func viewDidLoad() {
      super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        locationManager.delegate = self
        if NSString(string:UIDevice.currentDevice().systemVersion).doubleValue > 8 {
            locationManager.requestAlwaysAuthorization()
        }
        locationManager.desiredAccuracy=kCLLocationAccuracyBest
      }
    
      func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
        var speed: CLLocationSpeed = CLLocationSpeed()
        speed = locationManager.location.speed
        println(speed);
      }
    
      func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        if status != CLAuthorizationStatus.Denied{
            locationManager.startUpdatingLocation()
        }
      }
    }
    

    然后在您的 viewDidLoad 或任何地方,您都可以制作标签:

          myLabel = UILabel()
            myLabel.text        = "MySpeed: \(speed)"
             self.addChild(myLabel)
    

    只要确保“速度”变量在您尝试使用它的任何地方都在范围内(我没有演示)。

    它为我编译。希望这可以帮助。我以前没用过,但是有了搜索功能,我相信我可以在这里学到大部分东西:D

    【讨论】:

    • 非常感谢!一会儿我会告诉你结果!
    • 哦,等等,我忘记了标签的一部分,等一下
    • 我在标签部分添加了一个部分,我忘了初始化和声明它。 myLabel = UILabel() 现在工作
    • NP :) 请点击“向上箭头”并勾选这是否解决了您的问题 =]
    • 我即将成功!
    猜你喜欢
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    相关资源
    最近更新 更多