Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: Subclass MKPolyline

I'm developing an app that request multiple directions (MKDirectionsRequest) and draw the routes in a mapView, all ok.

But I'm facing a problem: I want to draw each route with different color.

The first idea was simple: use title/subtitle to 'tag' different MKPolyline so I can set the color I want in the delegate function:

mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer

but I don't like this solution because it's 'ugly' and I will have to parse a string the day I will have to pass different params (traffic ..)

The second simple solution was to subclass MKPolyline, yeh simple .. as MKPolyline doesn't have a designated initializer, this is impossible (is it ?)

[edit]: I want to create a subclass of MKPolyline to copy "on it" the already created MKPolyline returned by MKDirectionsRequest.routes but I can't figure out how to override the read-only params (Apple says that we should override them in the subclass and add the setter, but I have an infinite loop in the setter witch is .. normal)

if was using objC, it will be simple to "inject" code at runtime and add my params, but I'm using swift.

could anyone help on this, thanks.

like image 806
Red Mak Avatar asked Dec 15 '25 18:12

Red Mak


1 Answers

Simpler method not requiring a custom renderer :

import UIKit
import MapKit

class CustomPolyline : MKPolyline {
    var color: UIColor?
}

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // setup mapView
        mapView.delegate = self

        // set map view region
        let location : CLLocationCoordinate2D = CLLocationCoordinate2DMake(51.4987, 0.007);
        let viewRegion = MKCoordinateRegionMakeWithDistance(location, 400, 400)
        mapView.setRegion(viewRegion, animated:true )

        // add red line
        let coords1 = [CLLocationCoordinate2D(latitude: 51.499526, longitude: 0.004785),CLLocationCoordinate2D(latitude: 51.500007, longitude: 0.005493)]
        let polyline1 = CustomPolyline(coordinates: coords1, count: coords1.count)
        polyline1.color = UIColor.red
        mapView.add(polyline1)

        // add blue line
        let coords2 = [CLLocationCoordinate2D(latitude: 51.498103, longitude: 0.007574), CLLocationCoordinate2D(latitude: 51.498190, longitude: 0.009677)]
        let polyline2 = CustomPolyline(coordinates: coords2, count: coords2.count)
        polyline2.color = UIColor.blue
        mapView.add(polyline2)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        if overlay is CustomPolyline {
            let polylineRenderer = MKPolylineRenderer(overlay: overlay)
            polylineRenderer.strokeColor = (overlay as! CustomPolyline).color
            polylineRenderer.lineWidth = 4
            return polylineRenderer
        }
        return MKOverlayRenderer()
    }

}

ScreenShot

like image 121
CoderMike Avatar answered Dec 17 '25 10:12

CoderMike



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!