5

Based on what I found on this SO question (Touch events on MKMapView's overlays), I have implemented a way to intercept tap gesture on MKPolygon.

It was working fine in our app that was built using Xcode 4.6.3 against iOS 6. However things stopped working when I tried it on iOS 7 devices.

Specifically

    CLLocationCoordinate2D coord = [neighborhoodMap_ convertPoint:point
                                             toCoordinateFromView:neighborhoodMap_];

    // We get view from MKMapView's viewForOverlay.
    MKPolygonView *polygonView = (MKPolygonView*) view;
    CGPoint polygonViewPoint = [polygonView pointForMapPoint:mapPoint];
    BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polygonView.path,
                                                        NULL,
                                                        polygonViewPoint,
                                                        NO);

For some reason the call to CGPathContainsPoint no longer returns YES even the given coordinates is within the MKPolygonView. Not sure if anyone has hit this problem, but I would appreciate any insights you may have.

Thanks!

Community
  • 1
  • 1
dfujiwara
  • 353
  • 2
  • 11

3 Answers3

2

Since iOS 7 you need to use the MKOverlayRenderer:

BOOL tapInPolygon = NO;
MKOverlayRenderer * polygonRenderer = [mapView rendererForOverlay:polygonOverlay];
if ( [polygonRenderer isKindOfClass:[MKPolygonRenderer class]]) {

    //Convert the point
    CLLocationCoordinate2D  coordinate = [self.mapView convertPoint:tapPoint
                                               toCoordinateFromView:self.mapView];
    MKMapPoint mapPoint = MKMapPointForCoordinate(coordinate);
    CGPoint polygonViewPoint = [polygonRenderer pointForMapPoint:mapPoint];

    // with iOS 7 you need to invalidate the path, this is not required for iOS 8
    [polygonRenderer invalidatePath]; 

    tapInPolygon = CGPathContainsPoint(polygonRenderer.path, NULL, polygonViewPoint, NO);
}
mt81
  • 3,288
  • 1
  • 26
  • 35
1

I had the same problem and just reading through the docs I found that MKPolygonView has been deprecated in iOS7 and should use MKPolygonRenderer instead.

Bach
  • 2,684
  • 5
  • 26
  • 36
0

I was having the same problem and was able to fix it with a workaround, but it definitely looks like a bug on apple's end. I noticed that the "path" property was not NULL right as the MKpolygonView was created, but was NULL whenever I wanted to reference it. The solution is to add another property to the MKPolygonView subclass as follows:

@property CGPathRef savedPath;

and then you have to assign it when it's not NULL:

    polygonOverlay.savedPath = CGPathCreateCopy(polygonOverlay.path);

Then just check against self.savedPath whenever needed. Again this is not supposed to be a permanent solution, but will solve the issue of targeting apps to ios6 on ios7 devices.

RJDubz
  • 165
  • 1
  • 7
  • I use the following to create the overlay: `polygonOverlay = [[PolygonOverlay alloc] initWithPolygon:(MKPolygon*)overlay];` In the viewForOverlay where polygonOverlay is a subclass of MKPolygonView. After this it has a path property for me that can be saved. – RJDubz Sep 24 '13 at 20:43
  • I tried this approach, and once i reference .path to copy into .savedPath, my overlay no longer draws (and the CGPathContainsPoint hit testing still doesn't work). RJDubz perhaps you can post a more complete code sample? – sethpollack Sep 27 '13 at 19:17
  • see here for an answer that worked for me: http://stackoverflow.com/questions/19014926/detecting-a-point-in-a-mkpolygon-broke-with-ios7-cgpathcontainspoint – sethpollack Sep 27 '13 at 20:05
  • I also ran into the issue of it not drawing anymore. I had to play around with where the path is saved/refrenced. My solution may or not fully work for your situation since all of this is unsupported...but try and reference the .path property in a few different places in your code and see if you can find one where it is not NULL and where it still draws on the screen. The solution posted here should also work but I have not tested it to be sure: http://stackoverflow.com/a/19018733/627687 – RJDubz Sep 30 '13 at 18:53
  • I was having an issue with saving/caching the savedPath in a dictionary and trying to compute whether a given point on the map lies in any of the polygons. It seems the calculation is inaccurate if you zoom in/out on the map. I believe the cached path is no longer representative of what you see in the updated map then. – dfujiwara Oct 31 '13 at 18:20