Обнаружение точки в 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 и не будет определять точку с помощью пути.
Я пытаюсь найти документацию о том, что метод изменяется, но не может найти.
Любые идеи, почему это сломалось? Или новое решение?
Ответы
Ответ 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)