Ответ 1
По-видимому, когда вы добавляете свой путь безье к карте через:
[_mapView.layer addSublayer:shapeLayer];
он добавляет выше некоторый внутренний слой, который MKMapView
использует для рисования аннотаций. Если вы посмотрите на этот несколько смежный вопрос, вы увидите, что вы можете реализовать протокол MKMapViewDelegate
и получить обратные вызовы при добавлении новых аннотаций станций. Когда это произойдет, вы в основном проверяете иерархию просмотров недавно добавленных аннотаций и вставляете новый прозрачный слой UIView
под. Вы берете на себя все аннотации перед этим прозрачным UIView
.
// always remember to assign the delegate to get callbacks!
_mapView.delegate = self;
...
#pragma mark - MKMapViewDelegate
- (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views{
if (views.count > 0) {
UIView* firstAnnotation = [views objectAtIndex:0];
UIView* parentView = [firstAnnotation superview];
// NOTE: could perform this initialization in viewDidLoad, too
if (self.pathOverlay == nil){
// create a transparent view to add bezier paths to
pathOverlay = [[UIView alloc] initWithFrame: parentView.frame];
pathOverlay.opaque = NO;
pathOverlay.backgroundColor = [UIColor clearColor];
[parentView addSubview:pathOverlay];
}
// make sure annotations stay above pathOverlay
for (UIView* view in views) {
[parentView bringSubviewToFront:view];
}
}
}
Затем вместо добавления слоя формы в _mapView.layer
вы добавите его в свой прозрачный слой представления, также используя этот новый слой в преобразовании координат:
- (void)handleGesture:(UIPanGestureRecognizer*)gesture
{
CGPoint location = [gesture locationInView: self.pathOverlay];
if (gesture.state == UIGestureRecognizerStateBegan)
{
if (!shapeLayer)
{
shapeLayer = [[CAShapeLayer alloc] init];
shapeLayer.fillColor = [[UIColor clearColor] CGColor];
shapeLayer.strokeColor = [[UIColor greenColor] CGColor];
shapeLayer.lineWidth = 5.0;
[pathOverlay.layer addSublayer:shapeLayer]; // <- change here !!!
}
self.path = [[UIBezierPath alloc] init];
[path moveToPoint:location];
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
[path addLineToPoint:location];
shapeLayer.path = [path CGPath];
}
else if (gesture.state == UIGestureRecognizerStateEnded)
{
/*
* This code is the same as what you already have ...
*/
// But replace this next line with the following line ...
//CGPoint loc = [_mapView convertCoordinate:coords toPointToView:self];
CGPoint loc = [_mapView convertCoordinate:coords toPointToView: self.pathOverlay];
/*
* And again use the rest of your original code
*/
}
}
где я также добавил ivar (и свойство) для нового прозрачного слоя:
UIView* pathOverlay;
Я протестировал это с помощью фиктивной сетки станций и получил следующие результаты:
P.S. Я также рекомендую избавиться от ваших переменных static
. Просто сделайте их ivars/свойства вашего класса.