如何在Xcode 10中获得使用CLLocation的速度和距离?

问题描述 投票:0回答:1

我使用最新版本的Xcode,目前正在尝试为最新版本的IOS构建应用程序。该应用程序是一个活动跟踪程序,需要速度,距离,时间和位置。位置和时间工作正常,但速度和距离的代码不起作用。 UILabels不会改变。

let manager = CLLocationManager()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let location = locations[0]
    let span:MKCoordinateSpan =  MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
    let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
    let reigon:MKCoordinateRegion = MKCoordinateRegion(center: myLocation, span: span)
    map.setRegion(reigon, animated: true)
    self.map.showsUserLocation =  true
    self.map.userTrackingMode = .followWithHeading

    //Speed and distance
    let mps = location.speed
    let km = mps * 3.6
    if watch.isRunning {
        print(String(format: "%.2f", km))
        speedText.text = String(format: "%.2f", km)

        if startLocation == nil {
            startLocation = locations.first
        } else if let location = locations.last {
            traveledDistance += lastLocation.distance(from: location)
            print("Traveled Distance:",  traveledDistance)

            let dist = traveledDistance * 3.6

            speedText.text = String(format: "%.2f", dist)

            print("Straight Distance:", startLocation.distance(from: locations.last!))
        }
        lastLocation = locations.last

    } else {
        distanceText.text = String("00.00")
        speedText.text = String("00.00")
        return
    }

}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    if (error as? CLError)?.code == .denied {
        manager.stopUpdatingLocation()
        manager.stopMonitoringSignificantLocationChanges()
    }
}

这是我的完整代码......

import UIKit
import MapKit
import CoreLocation

class ExcersiseViewController: UIViewController {

var timerText: UILabel!
var speedText: UILabel!
var distanceText: UILabel!

var action: UIButton!
var map: MKMapView!
let watch = Stopwatch()
let saveSystem = SaveCompleted()

var startLocation: CLLocation!
var lastLocation: CLLocation!
var traveledDistance: Double = 0

override func viewDidLoad() {
    super.viewDidLoad()

    manager.delegate = self as? CLLocationManagerDelegate
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.requestWhenInUseAuthorization()
    manager.startUpdatingLocation()
    manager.distanceFilter = 10

    let lightGreyColor = UIColor(red: 68/255, green: 68/255, blue: 68/255, alpha: 1)

    view.backgroundColor = .black

    let bounds = UIScreen.main.bounds
    let width = bounds.size.width
    let height = bounds.size.height

    map = MKMapView(frame: CGRect(x: 0, y: height - (height / 2), width: width, height: height - (height / 2)))
    map.showsUserLocation =  true
    map.userTrackingMode = .followWithHeading

    action = UIButton(frame: CGRect(x: 0, y: 20, width: width, height: 50))
    action.backgroundColor = lightGreyColor
    action.setTitleColor(.white, for: .normal)
    action.addTarget(self, action: #selector(startStop), for: .touchUpInside)
    if watch.isRunning {
        action.setTitle("Stop", for: .normal)
    } else {
        action.setTitle("Start", for: .normal)
    }

    timerText = UILabel(frame: CGRect(x: 0, y: height / 7, width: width, height: 50))
    timerText.text = "00:00:00"
    timerText.textAlignment = .center
    timerText.textColor = .white
    timerText.font = UIFont(name: "Avenir Next", size: 60)

    speedText = UILabel(frame: CGRect(x: 0, y: height / 3, width: width, height: 50))
    speedText.text = "00.00"
    speedText.textAlignment = .left
    speedText.textColor = .white
    speedText.font = UIFont(name: "Avenir Next", size: 60)

    distanceText = UILabel(frame: CGRect(x: 0, y: height / 3, width: width, height: 50))
    distanceText.text = "00.00"
    distanceText.textAlignment = .right
    distanceText.textColor = .white
    distanceText.font = UIFont(name: "Avenir Next", size: 60)

    self.view.addSubview(distanceText)
    self.view.addSubview(speedText)
    self.view.addSubview(timerText)
    self.view.addSubview(action)
    self.view.addSubview(map)

}

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

let manager = CLLocationManager()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let location = locations[0]
    let span:MKCoordinateSpan =  MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
    let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
    let reigon:MKCoordinateRegion = MKCoordinateRegion(center: myLocation, span: span)
    map.setRegion(reigon, animated: true)
    self.map.showsUserLocation =  true
    self.map.userTrackingMode = .followWithHeading

    //Speed and distance
    let mps = location.speed
    let km = mps * 3.6
    if watch.isRunning {
        print(String(format: "%.2f", km))
        speedText.text = String(format: "%.2f", km)

        if startLocation == nil {
            startLocation = locations.first
        } else if let location = locations.last {
            traveledDistance += lastLocation.distance(from: location)
            print("Traveled Distance:",  traveledDistance)

            let dist = traveledDistance * 3.6

            speedText.text = String(format: "%.2f", dist)

            print("Straight Distance:", startLocation.distance(from: locations.last!))
        }
        lastLocation = locations.last

    } else {
        distanceText.text = String("00.00")
        speedText.text = String("00.00")
        return
    }

}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    if (error as? CLError)?.code == .denied {
        manager.stopUpdatingLocation()
        manager.stopMonitoringSignificantLocationChanges()
    }
}

@objc func updateElapsedTimeLabel(timer : Timer) {
    if watch.isRunning {
        let hours = Int(watch.elapsedTime/60/60)
        let minutes = Int(watch.elapsedTime.truncatingRemainder(dividingBy: 60)/60)
        let seconds = Int(watch.elapsedTime.truncatingRemainder(dividingBy: 60))
        timerText.text = String(format: "%02d:%02d:%02d", hours, minutes, seconds)
    } else {
        timer.invalidate()
    }
}

@objc func startStop() {
    if watch.isRunning {
        watch.stop()
        action.setTitle("Start", for: .normal)
        //Save code

        let time = timerText.text
        let distance = distanceText.text

        if time != "" && distance != "" {
            saveSystem.runFromView(info: "Activity data: Time taken: \(time), Distance travelled: \(distance)")
            timerText.text = "00:00:00"
            distanceText.text = "00.00"
            speedText.text = "00.00"
            self.dismiss(animated: true, completion: nil)

        } else {
            let alert = UIAlertController(title: "Alert", message: "There was an error saving the activity. We are sorry for the inconvinience. Please try again or contact support if the error persists.", preferredStyle: UIAlertController.Style.alert)
            alert.addAction(UIAlertAction(title: "Close", style: UIAlertAction.Style.default, handler: nil))
            self.present(alert, animated: true, completion: nil)
            return
        }
    } else {
        watch.start()
        Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(ExcersiseViewController.updateElapsedTimeLabel(timer:)), userInfo: nil, repeats: true)
        action.setTitle("Stop", for: .normal)
    }
}

}

我这里也有我的秒表脚本......注意:这部分工作和Xcode 9上使用的速度代码。

import Foundation

class Stopwatch {

private var startTime : NSDate?
var elapsedTime: TimeInterval {
    if let startTime = self.startTime {
        return -startTime.timeIntervalSinceNow
    } else {
        return 0
    }
}
var isRunning: Bool {
    return startTime != nil
}
func start() {
    startTime = NSDate()
}
func stop() {
    startTime = nil
}
}

有没有人对这个问题有所了解?我添加了Mapkit和CoreLocation包,并设置了正确的用法说明。注意:我已经以编程方式创建了整个视图,因此它没有链接到故事板。

ios swift mapkit core-location
1个回答
0
投票

您必须将CLLocationManagerDelegate设置为View Controller

所以替换

manager.delegate = self as? CLLocationManagerDelegate

manager.delegate = self 

并在这里添加CLLocationManagerDelegate

class ExcersiseViewController: UIViewController,CLLocationManagerDelegate {
 ....
}

协议enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.