iosmkmapviewmapkitmkoverlaymkoverlaypathrenderer

Adding MKOverlayPathRenderer as overlay to MKMapView gets exception


Everything said in topic, so here is the code

- (void)viewDidLoad
{
     [super viewDidLoad];
     // Do any additional setup after loading the view, typically from a nib.
     _pathRenderer = [[MKOverlayPathRenderer alloc] init];
     _pathRenderer.lineWidth = 8.0f;
     _pathRenderer.strokeColor = [UIColor redColor];
     _pathRenderer.path = CGPathCreateMutable();
     [_mapView addOverlay:_pathRenderer];
}

At the last line it drops with exception:

  Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MKOverlayPathRenderer boundingMapRect]: unrecognized selector 

It means that i'm using wrong class that don't implements MKOverlay, I got it, but as said in reference of MKOverlayPathRenderer - it does. So I'm a bit stuck with this problem.


Solution

  • MKOverlayPathRenderer does not implement the MKOverlay protocol.

    The addOverlay requires an object that conforms to the MKOverlay protocol.

    The object you're giving it doesn't do that and so you get that exception (objects that implement MKOverlay must have a boundingMapRect property).

    In your question, the statement:

    as said in reference of MKOverlayPathRenderer - it does

    doesn't make sense.

    The documentation does not say that MKOverlayPathRenderer implements MKOverlay. MKOverlayPathRenderer is a subclass of MKOverlayRenderer and NSObject. It conforms only to the NSObject protocol.


    An MKOverlayPathRenderer draws the visual representation of some model overlay object that conforms to MKOverlay.

    So there are two separate objects required (similar to how annotations work):

    1. The model of the overlay -- something that implements MKOverlay.
    2. The view of the overlay -- some subclass of MKOverlayRenderer (or MKOverlayView before iOS 7).

    The procedure is to first give the MKMapView the model object(s) using the addOverlay: or addOverlays: methods.

    Then in the rendererForOverlay delegate method, which the map view will call when it actually wants to display some overlay, you create and return a renderer (view) for the overlay in question.


    The code you have that creates a renderer would normally be in the rendererForOverlay delegate method and should use the initWithOverlay method (instead of init) and should pass the overlay model object for which you want to create the renderer.

    For the addOverlay, you would create some overlay model object -- either some standard class like MKPolyline, MKPolygon, MKCircle, or a custom class.


    But are you sure you need an MKOverlayPathRenderer?

    If you just want to draw a simple line, circle, or polygon, use the renderers already provided that automatically draw these objects for you. You will have a much easier time than creating your own subclass of MKOverlayPathRenderer.

    MKPolylineRenderer, MKPolygonRenderer, and MKCircleRenderer are built-in subclasses of MKOverlayPathRenderer that draw their related model overlays without you writing any drawing code.