Обнаружение точки в 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 и не обнаружит точку с путем.

Я пытаюсь найти любую документацию о том, что метод изменился, но не могу найти.

Есть идеи, почему это сломалось? Или новое решение?

4 ответа

Решение

По какой-то причине (возможно, ошибка), path возврат имущества NULL в текущем выпуске iOS 7.

Обходной путь - построить свой собственный CGPathRef от points многоугольника.
С этим методом вам не нужна ссылка на MKPolygonView или MKPolygonRenderer,

Например:

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,

У меня была такая же проблема. Решил это путем вызова invalidatePath для MKPolygonRenderer перед доступом к Path.

Проблема с вашим кодом в том, что метод

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

устарела в iOS 7 ( см. документацию), вместо этого следует использовать это:

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

Итак, чтобы ваш код работал правильно в iOS 7, вы должны заменить:

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

с

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

Проблема в том, что - rendererForOverlay: является новым в iOS 7, так что это изменение означает, что ваше приложение не работает в предыдущих версиях. Вы можете реализовать две версии метода и сделать вызов один или другой в зависимости от версии iOS.

Я не оценил производительность по сравнению с решением @Anna

Он работает прямо на 7.1, но не на 7.0.

Ответ jdehlin исправил проблему для меня с 7.0, т.е. призвание [view invalidatePath] перед каждым звонком

CGPathContainsPoint(polygonView.path, NULL, polygonViewPoint, FALSE)
Другие вопросы по тегам