I am trying to draw an MKPolyline
on a map. When I do a simulated run on the app, the location moves correctly but no line is drawn. How can I resolve this issue?
mapView.delegate = self
mapView.showsUserLocation = true
mapView.mapType = MKMapType(rawValue: 0)!
mapView.userTrackingMode = MKUserTrackingMode(rawValue: 2)!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
mapView.mapType = MKMapType(rawValue: 0)!
}
override func viewWillAppear(_ animated: Bool) {
locationManager.startUpdatingHeading()
locationManager.startUpdatingLocation()
}
override func viewWillDisappear(_ animated: Bool) {
locationManager.stopUpdatingHeading()
locationManager.stopUpdatingLocation()
}
// MARK: - CLLocationManager delegate
func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
//drawing path or route covered
if let oldLocationNew = oldLocation as CLLocation?{
let oldCoordinates = oldLocationNew.coordinate
let newCoordinates = newLocation.coordinate
var area = [oldCoordinates, newCoordinates]
var polyline = MKPolyline(coordinates: &area, count: area.count)
mapView.add(polyline)
}
//calculation for location selection for pointing annoation
if let previousLocationNew = previousLocation as CLLocation?{
//case if previous location exists
if previousLocation.distance(from: newLocation) > 200 {
addAnnotationsOnMap(locationToPoint: newLocation)
previousLocation = newLocation
}
}
else{
//case if previous location doesn't exists
addAnnotationsOnMap(locationToPoint: newLocation)
previousLocation = newLocation
}
}
// MARK: - MKMapView delegate
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if (overlay is MKPolyline) {
var pr = MKPolylineRenderer(overlay: overlay)
pr.strokeColor = UIColor.red
pr.lineWidth = 5
return pr
}
return nil
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if startDate == nil {
startDate = Date()
} else {
print("elapsedTime:", String(format: "%.0fs", Date().timeIntervalSince(startDate)))
timeLabel.text="\(Date().timeIntervalSince(startDate))"
}
if startLocation == nil {
startLocation = locations.first
} else if let location = locations.last {
traveledDistance += lastLocation.distance(from: location)
print("Traveled Distance:", traveledDistance)
distanceLabel.text="\(traveledDistance)"
print("Straight Distance:", startLocation.distance(from: locations.last!))
}
lastLocation = locations.last
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
if (error as? CLError)?.code == .denied {
manager.stopUpdatingLocation()
manager.stopMonitoringSignificantLocationChanges()
}
}
MKPolyline
should be drawn as the user moves.
The signature for mapView(_:rendererFor:)
is incorrect. It has changed. It is now:
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
switch overlay {
case let polyline as MKPolyline:
let renderer = MKPolylineRenderer(polyline: polyline)
renderer.strokeColor = .red
renderer.lineWidth = 5
return renderer
// you can add more `case`s for other overlay types as needed
default:
fatalError("Unexpected MKOverlay type")
}
}
If you add a print
statement or breakpoint inside your current method, I believe you will find that it’s not being called. And, of course, make sure that you’ve set the delegate
of your map view, either in IB or programmatically.
By the way, the old locationManager(_:didUpdateTo:from:)
is deprecated. Use locationManager(_:didUpdateLocations:)
instead. You’ll have to maintain your own reference to the savedLocation
and the savedPolyline
:
var savedLocation: CLLocation?
var savedPolyline: MKPolyline?
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last(where: { $0.horizontalAccuracy >= 0 }) else { return }
var polyline: MKPolyline?
if let oldCoordinate = savedLocation?.coordinate {
let coordinates = [oldCoordinate, location.coordinate]
polyline = MKPolyline(coordinates: coordinates, count: coordinates.count)
mapView.addOverlay(polyline!)
}
// if you want to remove the old one
//
// if let savedPolyline = savedPolyline {
// mapView.removeOverlay(savedPolyline)
// }
//
// savedPolyline = polyline
savedLocation = location
// ...
}