Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

По какой-то причине (возможно, ошибка) свойство 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 what CGPathContainsPoint wants.

BOOL pointIsInPolygon = CGPathContainsPoint(mpr, NULL, mapPointAsCGP, FALSE);

CGPathRelease(mpr);

Это также должно работать на iOS 6.
Однако вы можете выполнить эту ручную конструкцию, только если свойство overlay view path возвращает NULL.

Ответ 2

У меня была такая же проблема. Выбрал его, вызвав invalidatePath на MKPolygonRenderer, прежде чем перейти к пути.

Ответ 3

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

- (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

Ответ 4

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

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

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