Search code examples
iosobjective-cmapkitmkoverlaymkoverlaypathrenderer

MKMapViewDelegate: How to identifiy overlay in rendererForOverlay


I'm adding two different MKGeodesicPolyline instances to an MKMapView like this

CLLocation *LAX = [[CLLocation alloc] ...];
CLLocation *JFK = [[CLLocation alloc] ...];
CLLocation *LHR = [[CLLocation alloc] ...];

CLLocationCoordinate2D laxToJfkCoords[2] = {LAX.coordinate, JFK.coordinate};
CLLocationCoordinate2D jfkToLhrCoords[2] = {JFK.coordinate, LHR.coordinate};

MKGeodesicPolyline *laxToJfk = [MKGeodesicPolyline polylineWithCoordinates:laxToJfkCoords count:2];
MKGeodesicPolyline *jfkToLhr = [MKGeodesicPolyline polylineWithCoordinates:jfkToLhrCoords count:2];

[mapView addOverlay:laxToJfk];
[mapView addOverlay:jfkToLhr];

I want to render both of these overlays with different styles which need to be configured in the rendererForOverlay delegate method.

- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay {
    if (![overlay isKindOfClass:[MKPolyline class]]) {
        return nil;
    }

    MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:(MKPolyline *)overlay];
    renderer.lineWidth = 3.0f;

    // How to set different colors for LAX-JFK and JFK-LHR?
    renderer.strokeColor = [UIColor blueColor];

    return renderer;
}

My question is what options are there to identify the two different overlays in the above method?

Here's what I considered so far:

  1. Subclassing: Not an option because MKGeodesicPolyline is initialized through a static factory method.
  2. Keep references to the overlays in properties and then compare the delegate's overlay parameter against those. This does work but it feels a little clumsy. Also, for more than two overlays this approach would need to be extended by using an NSSet or an NSArray.

Is there anything else I could do to simplify this? It seems that MKGeodesicPolyline does not possess any properties that could be used for tagging.


Solution

  • One alternative to subclassing is to use associated objects. But its use is often discouraged.

    A longer, but more stable solution, is to make a custom MKOverlay and a MKOverlayRenderer that forward most of their implementations to a private instance of MKGeodesicPolyline and MKPolylineRenderer respectively. Then you can add a custom property to set the color.