14

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;
}
user2734323
  • 706
  • 1
  • 8
  • 19

7 Answers7

17

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;
Andrew
  • 3,874
  • 5
  • 39
  • 67
  • Yes, I have the delegate in header file... @interface MapTrackerViewController : UIViewController { MKMapView *mapView; ... } I have delegate assigned in drawPolyline method ([mapView setDelegate:self];). Please find the code in my original post. It was working in iOS6. In iOS7, they removed viewforOverlay method. Now, I am trying to implement rendererForOverlay. But it doesn't get called. – user2734323 Sep 21 '13 at 22:20
2

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!

Sam Soffes
  • 14,831
  • 9
  • 76
  • 80
1

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!

Pei
  • 11,452
  • 5
  • 41
  • 45
  • Well, I also had another case and I override MKMapView and it relays all the delegate methods such as mapView: viewForOverlay: And I had to add another relay of mapView: rendererForOverlay: – Pei Sep 30 '13 at 08:29
1

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

Paco
  • 4,520
  • 3
  • 29
  • 53
timothy
  • 11
  • 1
0

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.

Community
  • 1
  • 1
Tony
  • 11
  • 5
0

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.
Paresh Mayani
  • 127,700
  • 71
  • 241
  • 295
Elise van Looij
  • 4,162
  • 3
  • 29
  • 52
0

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)
Hardy_Germany
  • 1,259
  • 13
  • 19