检测到一个MKPolygon的一个点打破了iOS7(CGPathContainsPoint)

在今年早些时候我问到的一个SO问题中 ,我得到了这样一段代码:

MKPolygonView *polygonView = (MKPolygonView *)[self.mapView viewForOverlay:polygon]; MKMapPoint mapPoint = MKMapPointForCoordinate(tapCoord); CGPoint polygonViewPoint = [polygonView pointForMapPoint:mapPoint]; if (CGPathContainsPoint(polygonView.path, NULL, polygonViewPoint, FALSE)) { // do stuff } 

这直到iOS7才有效。 它现在总是返回false,并且不会检测到具有path的点。

我试图find任何文件说明方法改变,但找不到任何。

任何想法,为什么它坏了? 还是新的解决scheme?

出于某种原因(可能是一个bug),在当前版本的iOS 7中, path属性返回NULL

解决方法是从多边形的points构build自己的CGPathRef
使用这种方法,您不需要对MKPolygonViewMKPolygonRenderer

例如:

 CGMutablePathRef mpr = CGPathCreateMutable(); MKMapPoint *polygonPoints = myPolygon.points; //myPolygon is the MKPolygon for (int p=0; p < myPolygon.pointCount; p++) { MKMapPoint mp = polygonPoints[p]; if (p == 0) CGPathMoveToPoint(mpr, NULL, mp.x, mp.y); else CGPathAddLineToPoint(mpr, NULL, mp.x, mp.y); } CGPoint mapPointAsCGP = CGPointMake(mapPoint.x, mapPoint.y); //mapPoint above is the MKMapPoint of the coordinate we are testing. //Putting it in a CGPoint because that's what CGPathContainsPoint wants. BOOL pointIsInPolygon = CGPathContainsPoint(mpr, NULL, mapPointAsCGP, FALSE); CGPathRelease(mpr); 

这也应该在iOS 6上工作。
但是,只有覆盖视图的path属性返回NULL才可能需要执行此手动构build。

我有同样的问题。 在访问Path之前,通过在MKPolygonRenderer上调用invalidatePath来解决这个问题。

你的代码的问题是该方法

 - (MKOverlayView *)viewForOverlay:(id < MKOverlay >)overlay 

已经在iOS 7中被弃用( 请参阅文档 ),您应该使用它来代替:

 - (MKOverlayRenderer *)rendererForOverlay:(id < MKOverlay >)overlay 

所以,为了让你的代码在iOS 7中正常工作,你必须replace:

 MKPolygonView *polygonView = (MKPolygonView *)[self.mapView viewForOverlay:polygon]; 

 MKPolygonRenderer *polygonView = (MKPolygonRenderer *)[self.mapView rendererForOverlay:polygon]; 

这个问题是- rendererForOverlay:在iOS 7中是新的,所以这个改变使得你的应用程序不能在以前的版本中运行。 您可以实现两个版本的方法,并根据iOS版本调用一个或另一个版本。

与@Anna解决scheme相比,我还没有介绍这方面的performance

它直接在7.1上工作,但不在7.0上。

jdehlin响应修复了7.0的问题,即。 在每次调用之前调用[view invalidatePath]

 CGPathContainsPoint(polygonView.path, NULL, polygonViewPoint, FALSE)