如何将UIBezierPath带到MKAnnotation对象的后面?

在我的应用程序,用户在地图上绘制一个形状,并使用UIBeizerPath我正在绘制该path。 然后根据path的坐标,我显示只在该区域的结果。 一切都很好,除了现在注释掉落在地图视图上时,引脚看起来像是在path的后面,这意味着path看起来在前面。

我正在使用此代码来显示注释和path:

-(void)clearAnnotationAndPath:(id)sender { [_mapView removeAnnotations:_mapView.annotations]; path = [UIBezierPath bezierPath]; [shapeLayer removeFromSuperlayer]; } - (void)handleGesture:(UIPanGestureRecognizer *)gesture { CGPoint location = [gesture locationInView:_pathOverlay]; if (gesture.state == UIGestureRecognizerStateBegan) { shapeLayer = [[CAShapeLayer alloc] init]; shapeLayer.fillColor = [[UIColor clearColor] CGColor]; shapeLayer.strokeColor = [[UIColor greenColor] CGColor]; shapeLayer.lineWidth = 5.0; //[_mapView.layer addSublayer:shapeLayer]; [pathOverlay.layer addSublayer:shapeLayer]; path = [UIBezierPath bezierPath]; [path moveToPoint:location]; } else if (gesture.state == UIGestureRecognizerStateChanged) { [path addLineToPoint:location]; shapeLayer.path = [path CGPath]; } else if (gesture.state == UIGestureRecognizerStateEnded) { // MKMapView *mapView = (MKMapView *)gesture.view; [path addLineToPoint:location]; [path closePath]; allStations = [RoadmapData sharedInstance].data; for (int i=0; i<[allStations count]; i++) { NSDictionary * itemNo = [allStations objectAtIndex:i]; NSString * fullAddress = [NSString stringWithFormat:@"%@,%@,%@,%@",[itemNo objectForKey:@"address"],[itemNo objectForKey:@"city"],[itemNo objectForKey:@"state"],[itemNo objectForKey:@"zip"]]; CLGeocoder * geoCoder = [[CLGeocoder alloc]init]; [geoCoder geocodeAddressString:fullAddress completionHandler:^(NSArray *placemarks, NSError *error) { if (error) { NSLog(@"Geocode failed with error: %@", error); return; } if(placemarks && placemarks.count > 0) { CLPlacemark *placemark = placemarks[0]; CLLocation *location = placemark.location; CLLocationCoordinate2D coords = location.coordinate; CGPoint loc = [_mapView convertCoordinate:coords toPointToView:_pathOverlay]; if ([path containsPoint:loc]) { NSString * name = [itemNo objectForKey:@"name"]; stationAnn = [[LocationAnnotation alloc]initWithCoordinate:coords Title:name subTitle:@"Wells Fargo Offer" annIndex:i]; stationAnn.tag = i; [_mapView addAnnotation:stationAnn]; } else{ NSLog(@"Out of boundary"); } } }]; [self turnOffGesture:gesture]; } } } - (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views{ if (views.count > 0) { UIView* firstAnnotation = [views objectAtIndex:0]; UIView* parentView = [firstAnnotation superview]; if (_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]; } } } 

也有一次,我从这回来查看,再次来到它甚至没有绘制的path。

请帮忙。

谢谢,

显然,当你通过以下方法将你的贝塞尔path添加到地图中:

  [_mapView.layer addSublayer:shapeLayer]; 

它被添加到MKMapView用来绘制注释的一些内部层之上 。 如果你看看这个有点相关的问题 ,你会看到你可以实现MKMapViewDelegate协议,并添加新的电台注释时获得callback。 发生这种情况时,您基本上会检查新添加的注释的视图层次,并下面插入一个新的透明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 */ } } 

在那里我还为新的透明层添加了伊娃 (和财产):

 UIView* pathOverlay; 

我用台站的一个假网格testing了这个结果,得到如下结果:

在这里输入图像说明

PS我也build议摆脱你的staticvariables。 只要让他们成为你的class级的属性。