我正在为我的一门课程制作一个应用程序。它应该跟踪行驶的距离,并更新标签以显示他们走了多远。当我打开应用程序时,它会询问我是否允许跟踪位置。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包含所有必要的与位置相关的隐私字符串(我通常只把所有三个放在一起以覆盖所有基础)。