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