定位工作,但它不能跟踪我在Swift 3中行进的距离



我正在为我的一门课程制作一个应用程序。它应该跟踪行驶的距离,并更新标签以显示他们走了多远。当我打开应用程序时,它会询问我是否允许跟踪位置。mapView可以工作,它跟随位置,但标签永远不会更新以显示行进的距离。我在下面添加了我的代码,任何帮助都是非常感激的!

    //
    //  ViewController.swift
    //  location_tracker
    //
    //  Created by Dale McCaughan on 2016-10-19.
    //  Copyright © 2016 Dale McCaughan. All rights reserved.
    //
    import UIKit
    import CoreLocation
    import MapKit
    class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
    @IBOutlet weak var theMap: MKMapView!
    @IBOutlet weak var l: UILabel!
    let locationManager = CLLocationManager()
    var startLocation: CLLocation!
    var monitoredRegions: Dictionary<String, NSDate> = [:]
    override func viewWillAppear(_ animated: Bool) {
        self.navigationController?.isNavigationBarHidden =  true
        self.navigationController?.isToolbarHidden = false;
    //Status bar style and visibility
    UIApplication.shared.statusBarStyle = .lightContent
    //Change status bar color
    let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
    //if statusBar.respondsToSelector("setBackgroundColor:") {
    statusBar.backgroundColor = UIColor.white
    //}
    UIToolbar.appearance().backgroundColor = UIColor.white
}
override func viewDidLoad() {
    super.viewDidLoad()
    //Setup the Location Manager
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    //Setup the Map View
    theMap.delegate = self
    theMap.showsUserLocation = true
    theMap.userTrackingMode = .follow
    // setup test data
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    // status is not determined
    if CLLocationManager.authorizationStatus() == .notDetermined {
        locationManager.requestAlwaysAuthorization()
    }
        // authorization were denied
    else if CLLocationManager.authorizationStatus() == .denied {
        showAlert("Location services were previously denied. Please enable location services for this app in Settings.")
    }
        // we do have authorization
    else if CLLocationManager.authorizationStatus() == .authorizedAlways {
        locationManager.startUpdatingLocation()
    }
}
// MARK: - MKMapViewDelegate
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    let circleRenderer = MKCircleRenderer(overlay: overlay)
    circleRenderer.strokeColor = UIColor.red
    circleRenderer.lineWidth = 1.0
    return circleRenderer
}
@IBAction func resetDistance(_ sender: AnyObject) {
    startLocation = nil
}
// MARK: - CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
    showAlert("enter (region.identifier)")
    monitoredRegions[region.identifier] = Date() as NSDate?
    l.text = "in location manager1"
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
    showAlert("exit (region.identifier)")
    monitoredRegions.removeValue(forKey: region.identifier)
    l.text = "in location manager2"
}
var lastLocation: CLLocation!
var traveledDistance:Double = 0
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
    if let firstLocation = locations.first as? CLLocation
    {
        theMap.setCenter(firstLocation.coordinate, animated: true)
        let region = MKCoordinateRegionMakeWithDistance(firstLocation.coordinate, 1000, 1000)
        theMap.setRegion(region, animated: true)
        if let oldLocation = lastLocation {
            let delta: CLLocationDistance = firstLocation.distance(from: lastLocation)
            traveledDistance += delta
        }
        lastLocation = firstLocation
    }
    l.text = String(format: "%.3f", traveledDistance/1000) + " kilometers"
}
// MARK: - Helpers
func showAlert(_ title: String) {
    let alert = UIAlertController(title: title, message: nil, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in
        alert.dismiss(animated: true, completion: nil)
    }))
    self.present(alert, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}

试试这个:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let firstLocation = locations.first

您正在使用的委托签名不完全是委托所寻找的。校正签名后,您不再需要as CLLocation强制转换了。

我验证了它与该更改一起工作。为了将来的参考,你可以在didupdatlocations设置一个断点,你会马上看到它没有被调用,然后从那里向后工作。

还要确保Info。plist包含所有必要的与位置相关的隐私字符串(我通常只把所有三个放在一起以覆盖所有基础)。

最新更新