user2511882
user2511882

Reputation: 9152

MKPolyLine Swift 4

I am trying to learn MapKit and add some MKPolyLine as an overlay. Couple of questions:

  1. What is the difference between MKPolyLine and MKPolyLineView. Which one should be used when?

  2. For the MKPolyLine init method one of the parameter is a generic type(MKMapPoint) of UnsafePointer? Not really sure what is that supposed to mean. Looking up the various SO questions, it seems we are supposed to pass the memory address of the CLLocationCoordinate2D struct as a parameter, but it doesn't work for me.

    let testline = MKPolyline()
    let coords1 = CLLocationCoordinate2D(latitude: 52.167894, longitude: 17.077399)
    let coords2 = CLLocationCoordinate2D(latitude: 52.168776, longitude: 17.081326)
    let coords3 = CLLocationCoordinate2D(latitude: 52.167921, longitude: 17.083730)
    let testcoords:[CLLocationCoordinate2D] = [coords1,coords2,coords3]
    
    
    let line = MKPolyline.init(points: &testcoords, count: testcoords.count)
    
    mapView.add(testline)
    

I keep getting a "& is not allowed passing array value as 'UnsafePointer<MKMapPoint>" argument".

What is wrong here?

Upvotes: 2

Views: 6251

Answers (2)

OOPer
OOPer

Reputation: 47886

1.

MKPolyLine is a class which holds multiple map-coordinates to define the shape of a polyline, very near to just an array of coordinates. MKPolyLineView is a view class which manages the visual representation of the MKPolyLine. As mentioned in the Kane Cheshire's answer, it's outdated and you should use MKPolyLineRenderer.

Which one should be used when?

You need to use both MKPolyLine and MKPolyLineRenderer as in the code below.


2.

MKPolyLine has two initializers:

When you want to pass [CLLocationCoordinate2D] to MKPolyLine.init, you need to use init(coordinates:count:).

(Or you can create an Array of MKMapPoint and pass it to init(points:count:).)

And when you want to pass an immutable Array (declared with let) to UnsafePointer (non-Mutable), you have no need to prefix &.


The code below is actually built and tested with Xcode 9 beta 3:

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let coords1 = CLLocationCoordinate2D(latitude: 52.167894, longitude: 17.077399)
        let coords2 = CLLocationCoordinate2D(latitude: 52.168776, longitude: 17.081326)
        let coords3 = CLLocationCoordinate2D(latitude: 52.167921, longitude: 17.083730)
        let testcoords:[CLLocationCoordinate2D] = [coords1,coords2,coords3]

        let testline = MKPolyline(coordinates: testcoords, count: testcoords.count)
        //Add `MKPolyLine` as an overlay.
        mapView.add(testline)

        mapView.delegate = self

        mapView.centerCoordinate = coords2
        mapView.region = MKCoordinateRegion(center: coords2, span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02))
    }

    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        //Return an `MKPolylineRenderer` for the `MKPolyline` in the `MKMapViewDelegate`s method
        if let polyline = overlay as? MKPolyline {
            let testlineRenderer = MKPolylineRenderer(polyline: polyline)
            testlineRenderer.strokeColor = .blue
            testlineRenderer.lineWidth = 2.0
            return testlineRenderer
        }
        fatalError("Something wrong...")
        //return MKOverlayRenderer()
    }

}

Upvotes: 12

Kane Cheshire
Kane Cheshire

Reputation: 1712

Change testCoords to be var instead of let. It needs to be mutable (variable) to be passed in as a pointer.

You're also trying to pass an array of CLLocationCoordinate2Ds into an argument that expects an array of MKMapPoints. Either convert your coordinates into points or use the function that takes an array of coordinates instead.

MKPolyLineView is an old way of rendering lines onto maps, Apple's docs say to use MKPolylineRenderer from iOS 7 and onwards: https://developer.apple.com/documentation/mapkit/mkpolylineview

Upvotes: 0

Related Questions