MKPolyLine not appearing on MapView in Swift
Asked Answered
B

2

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?

Broadbent answered 26/3, 2015 at 11:55 Comment(6)
Does your viewController conform to the MKMapViewDelegate protocol?Cytolysin
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..<?Caesaria
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.Broadbent
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?Caesaria
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!Broadbent
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.Caesaria
B
8

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

mapView.delegate = self
Broadbent answered 26/3, 2015 at 13:37 Comment(0)
T
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()
    }
Tetherball answered 11/5, 2017 at 5:8 Comment(1)
rendererFor is a crucial adjective. Without it, you won't get the overlay drawn.Maisonette
B
8

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

mapView.delegate = self
Broadbent answered 26/3, 2015 at 13:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.