在iOS7上的MKMapView中检测MKPolygonView的轻拍

5
根据我在这个SO问题(MKMapView的覆盖物上的触摸事件)中发现的内容,我实现了一种拦截MKPolygon上的轻击手势的方法。
在使用Xcode 4.6.3针对iOS 6构建的应用程序中,它运行良好。但是当我在iOS 7设备上尝试时,它停止工作了。
具体来说:
    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);

由于某种原因,对于MKPolygonView中给定的坐标,CGPathContainsPoint方法不再返回YES。不确定是否有人遇到过这个问题,但我将感激您提供的任何见解。

谢谢!


原来 polygonView 的路径属性是 NULL。这绝对是一个奇怪的 bug。 - dfujiwara
肯定是个bug,我也遇到了同样的问题。向苹果提交一个工单吧。 - Dwill
是的,我已经向苹果提交了一个带有示例应用程序的错误报告。希望他们能在iOS7 GA中修复它...祈祷好运。 - dfujiwara
完全相同的问题。在iOS6上运行良好!有趣的是,尽管路径为空,但CGPathContainsPoint对于第一次点击返回True。但是第二次点击在完全相同的位置不起作用。 - Bach
苏富比,苹果有回复你的漏洞报告吗? - Dwill
很遗憾,苹果还没有回复我。 - dfujiwara
3个回答

2

iOS 7及以后的版本需要使用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);
}

1

我曾经遇到同样的问题,在阅读文档时发现MKPolygonView已在iOS7中弃用,应改为使用MKPolygonRenderer。


请注意,MKPolygonRenderer仅适用于iOS7。 - sethpollack

0

我曾经遇到过同样的问题,并通过一种变通方法解决了它,但这明显是苹果的一个bug。我注意到在创建MKpolygonView时,“path”属性不为NULL,但每当我想引用它时,它就会变成NULL。解决方案是在MKPolygonView子类中添加另一个属性,如下所示:

@property CGPathRef savedPath;

然后当它不为NULL时,你必须进行分配:

    polygonOverlay.savedPath = CGPathCreateCopy(polygonOverlay.path);

然后只需在需要时检查self.savedPath即可。再次强调,这不是一个永久性的解决方案,但可以解决在iOS7设备上针对iOS6应用程序的问题。


我使用以下代码创建覆盖层:polygonOverlay = [[PolygonOverlay alloc] initWithPolygon:(MKPolygon*)overlay]; 在viewForOverlay中,polygonOverlay是MKPolygonView的子类。之后,它会为我提供一个路径属性,可以保存。 - RJDubz
我尝试了这种方法,一旦我引用.path复制到.savedPath中,我的叠加层就不再绘制(而CGPathContainsPoint命中测试仍然无法工作)。RJDubz也许你可以发布一个更完整的代码示例? - sethpollack
这里有一个对我有效的答案:https://dev59.com/Y2Mk5IYBdhLWcg3wvAVo - sethpollack
我也遇到了它不再绘制的问题。我必须尝试保存/引用路径的位置。我的解决方案可能无法完全适用于您的情况,因为所有这些都是不受支持的...但请尝试在代码中的几个不同位置引用.path属性,并查看是否可以找到其中一个不为NULL且仍在屏幕上绘制的位置。此处发布的解决方案也应该有效,但我没有测试过以确保:https://dev59.com/Y2Mk5IYBdhLWcg3wvAVo#19018733 - RJDubz
我在保存/缓存savedPath到字典时遇到了问题,尝试计算地图上给定点是否位于任何多边形中。如果你放大/缩小地图,似乎计算是不准确的。我认为缓存的路径不再代表更新后的地图。 - dfujiwara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接