8

I have the following code in Swift to add an MKPolyline to a MapView. XCode isn't telling me there's an issue, and as far as I've read, this should be working.

Outlet for the MapView:

@IBOutlet weak var mapView: MKMapView!

Variable to hold the coordinates:

var coordinates: [CLLocationCoordinate2D] = []

Get my saved coordinates from Core Data:

var contextMap = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext!
var requestMap = NSFetchRequest(entityName: "Locations")
let predMap = NSPredicate(format: "game = %d", passedGameNumber)
requestMap.predicate = predMap
requestMap.sortDescriptors = [NSSortDescriptor(key:"time", ascending: false)]
    self.locationsList = contextMap.executeFetchRequest(requestMap, error: nil)! as [Locations]

Add the coordinates from Core Data to my new array:

for index in 1..<self.locationsList.count{
    var lat = Double(self.locationsList[index].latitude)
    var long = Double(self.locationsList[index].longitude)
    var coordinatesToAppend = CLLocationCoordinate2D(latitude: lat, longitude: long)
    coordinates.append(coordinatesToAppend)
}

Create the polyline:

var polyLine = MKPolyline(coordinates: &coordinates, count: coordinates.count)

Add the overlay:

self.mapView.addOverlay(polyLine, level: MKOverlayLevel.AboveRoads)

Add it to the MapView:

func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
    if overlay.isKindOfClass(MKPolyline) {
        // draw the track
        let polyLine = overlay
        let polyLineRenderer = MKPolylineRenderer(overlay: polyLine)
        polyLineRenderer.strokeColor = UIColor.blueColor()
        polyLineRenderer.lineWidth = 2.0

        return polyLineRenderer
    }

    return nil
}

I simply get a blank MapView. I can print the coordinates array to the console, so I know the data has been added. Any ideas?

Adam Johnson
  • 673
  • 9
  • 18
  • Does your viewController conform to the `MKMapViewDelegate` protocol? – zisoft Mar 26 '15 at 12:21
  • Is the map view's delegate outlet connected to the view controller? After addOverlay, does self.mapView.overlays.count say 1? Does the rendererForOverlay method actually get called (put a breakpoint or println there)? Are the coordinates valid/backwards (it happens)? Unrelated, but shouldn't `for index in 1..<` be `for index in 0..<`? –  Mar 26 '15 at 12:21
  • Thanks both. Anna, I added the breakpoint and it seems that it's not being called. Might be a silly question, but how can I resolve that? I'm sure it's simple. Regarding the index in 1 comment, it was giving me an error when I had 0 in there before - that now seems to be working with 1. – Adam Johnson Mar 26 '15 at 12:44
  • 1
    You must make sure that the map view's delegate is set otherwise the delegate methods won't get called no matter what. In the storyboard, connect the map's delegate outlet to the view controller. Or, in code, in viewDidLoad, after super.viewDidLoad, do `mapView.delegate = self`. Arrays start at index 0. By starting at 1, you are skipping the first coordinate. What error were you getting with 0? –  Mar 26 '15 at 13:08
  • Thank you, thank you, thank you! Anna, you've no idea how long I've had MKPolyline problem sat on my to-do list - I knew it had to be something simple! I'm new to the site, so not sure if I should add that as an answer to the question? Regarding the error with 0, I unfortunately can't recall. I found the solution somewhere on Stack Overflow though, but obviously I needn't have bothered! – Adam Johnson Mar 26 '15 at 13:16
  • You can answer it or delete the question -- failing to set the delegate is a common mistake (though too many question deletions may cause other problems for you). I would look into the error starting at index 0 though. –  Mar 26 '15 at 13:21

2 Answers2

9

The above method will be written like this in Swift3:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        if overlay.isKind(of: MKPolyline.self) {
            // draw the track
            let polyLine = overlay
            let polyLineRenderer = MKPolylineRenderer(overlay: polyLine)
            polyLineRenderer.strokeColor = UIColor.blue
            polyLineRenderer.lineWidth = 2.0

            return polyLineRenderer
        }

        return MKPolylineRenderer()
    }
Tripti Kumar
  • 1,559
  • 14
  • 28
8

As posted in the comments, the code in the question was fine. I simply wasn't setting the delegate.

mapView.delegate = self
Adam Johnson
  • 673
  • 9
  • 18