user2734323
user2734323

Reputation: 706

MKMapView - rendererForOverlay not called

I recently started learning objectiveC and started developing an app in iOS6.

Now, I am trying to convert it for iOS7 and facing issues with MKMap.

In iOS6, I was using viewForOverlay.

In iOS7, I am changing it to renderForOverlay. But, my application is not calling mapView:rendererForOverlay. Below is my code. Appreciate your help.

- (void) drawPolyline:(NSArray *)locations
{
    [mapView setDelegate:self];
    ...
    ...

    self.polyline = [MKPolyline polylineWithCoordinates:locationCoordinate2DArray count:numberOfLocations];
    free(locationCoordinate2DArray);
    [mapView addOverlay:self.polyline];
    [mapView setNeedsDisplay];
}

- (MKOverlayRenderer*)mapView:(MKMapView*)mapView rendererForOverlay:(id <MKOverlay>)overlay
{
    MKPolylineRenderer* lineView = [[MKPolylineRenderer alloc] initWithPolyline:self.polyline];
    lineView.strokeColor = [UIColor blueColor];
    lineView.lineWidth = 7;
    return lineView;
}

Upvotes: 14

Views: 13311

Answers (7)

Hardy_Germany
Hardy_Germany

Reputation: 1279

Just a hint for such like me, which struggle with IOS 13 on that. It looks, as IOS 13 ignores something like:

// self is a MKTileOverlayRenderer
// the code is called, if a method has produced a tile for a given MKMapRect

// tell the system that we are ready
DispatchQueue.main.async(execute: {

    // invalidate the mapRect
    self.setNeedsDisplay(mapRect)

})

This code worked fine in IOS 10 - IOS 12, but now you have to add the zoomScale to the setNeedsDisplay(), otherwise it seems to be ignored by IOS 13... cost me 4 hours to sort it out ;-)

self.setNeedsDisplay(mapRect, zoomScale: zoomScale)

Upvotes: 0

Sam Soffes
Sam Soffes

Reputation: 14935

Like others have said, be sure you set your delegate before adding them. Use the addOverlay:level: method since addOverlay: will be deprecated (according to the comment in the header).

My issue was something dumb. I had lat and long switched by mistake for my polygon's points. Be sure to double check that if they still aren't showing up.

You might also try logging pointCount on your polygon to make sure they are being set properly.

Related, this is how to do it in Swift:

// Get your coordinates from somewhere as an [CLLocationCoordinate2D] array
// If you already have them, make a local mutable copy
var coordinates = [CLLocationCoordinate2D]()

// Create your polygon
let polygon = MKPolygon(coordinates: &coordinates, count: coordinates.count)

Hopefully this saves you some time!

Upvotes: 2

Elise van Looij
Elise van Looij

Reputation: 4232

For me, the solution involved two steps:

  1. Set the delegate first, before adding the overlay. As soon as the overlay is added, the delegate methods will be called.
  2. Check the delegate. Stupidly, I had a local property called delegate in my code. In iOS 6, it didn't matter, in iOS 7 it did. As soon as I removed that stray delegate, rendererForOverlay: got called.

Upvotes: 0

Tony
Tony

Reputation: 11

I just finished my experiments with this method and I found that only nib-file placed MKMapView and @property (weak, nonatomic) IBOutlet MKMapView *mapView; fixed this issue. Also here is checklist.

Upvotes: 0

timothy
timothy

Reputation: 11

If there is only one point in locationCoordinate2DArray,mapView:rendererForOverlay would not be called.

Upvotes: 1

Pei
Pei

Reputation: 11643

OK, I had the same issue and finally found the case. We have to use [MKMapView addOverlay: level:] instead of [MKMapView addOverlay:]. It triggers rendererForOverlay rather than viewForOverlay of the delegate. Hope this would be helpful for you iOS 7 lovers!

Upvotes: 1

Mike Petrogeorge
Mike Petrogeorge

Reputation: 171

I am assuming that you did declare the MKMapViewDelegate delegate in your header file via the @interface statement:

However, did you assign the delegate in the viewDidLoad (or where you think its appropriate) method?

self.mapView.delegate = self;

Upvotes: 17

Related Questions