Ios 如何将UIBezierPath带到MKAnnotation对象的后面?
在我的应用程序中,用户在地图上绘制一个形状,并使用UIBeizerPath绘制该路径。然后根据路径的坐标,我显示的结果仅在该区域。一切都很好,只是现在当注释掉在地图视图上时,针脚看起来像在路径后面,这意味着路径看起来在前面 我使用以下代码显示注释和路径:Ios 如何将UIBezierPath带到MKAnnotation对象的后面?,ios,objective-c,mkmapview,uibezierpath,Ios,Objective C,Mkmapview,Uibezierpath,在我的应用程序中,用户在地图上绘制一个形状,并使用UIBeizerPath绘制该路径。然后根据路径的坐标,我显示的结果仅在该区域。一切都很好,只是现在当注释掉在地图视图上时,针脚看起来像在路径后面,这意味着路径看起来在前面 我使用以下代码显示注释和路径: -(void)clearAnnotationAndPath:(id)sender { [_mapView removeAnnotations:_mapView.annotations]; path = [UIBezierPat
-(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];
}
}
}
-(无效)clearAnnotationAndPath:(id)发送方{
[[u mapView removeAnnotations:[u mapView.annotations];
路径=[UIBezierPath bezierPath];
[shapeLayer从SuperLayer移除];
}
-(无效)手势:(UIPangestureRecognitor*)手势
{
CGPoint位置=[手势位置视图:_pathOverlay];
if(signature.state==UIGestureRecognitizerStateStart)
{
shapeLayer=[[CAShapeLayer alloc]init];
shapeLayer.fillColor=[[UIColor clearColor]CGColor];
shapeLayer.strokeColor=[[UIColor greenColor]CGColor];
shapeLayer.lineWidth=5.0;
//[\u mapView.layer addSublayer:shapeLayer];
[pathOverlay.layer addSublayer:shapeLayer];
路径=[UIBezierPath bezierPath];
[路径移动点:位置];
}
else if(signature.state==UIgestureRecognitizerStateChanged)
{
[路径addLineToPoint:位置];
shapeLayer.path=[path CGPath];
}
else if(signature.state==UIgestureRecognitizerStateEnded)
{
//MKMapView*mapView=(MKMapView*)手势.view;
[路径addLineToPoint:位置];
[path closePath];
allStations=[RoadmadData sharedInstance]。数据;
对于(int i=0;i 0)
{
CLPlacemark*placemark=placemarks[0];
CLLocation*location=placemark.location;
CLLocationCoordinate2D coords=location.coordinate;
CGPoint loc=[[u地图视图转换坐标:坐标系拓扑视图:];
if([路径包含点:loc])
{
NSString*name=[itemNo objectForKey:@“name”];
stationAnn=[[LocationAnnotation alloc]initWithCoords标题:名称副标题:@“富国银行报价”annIndex:i];
stationAnn.tag=i;
[_MapViewAddAnnotation:stationAnn];
}
否则{
NSLog(“境外”);
}
}
}];
[自我关闭手势:手势];
}
}
}
-(void)地图视图:(MKMapView*)aMapView didaddannotationview:(NSArray*)视图{
如果(views.count>0){
UIView*firstAnnotation=[views objectAtIndex:0];
UIView*parentView=[firstAnnotation superview];
如果(_pathOverlay==nil){
//创建透明视图以将贝塞尔路径添加到
pathOverlay=[[UIView alloc]initWithFrame:parentView.frame];
pathOverlay.不透明=否;
pathOverlay.backgroundColor=[UIColor clearColor];
[parentView addSubview:pathOverlay];
}
//确保注释位于PathVerlay上方
用于(UIView*视图中的视图){
[父视图将子视图带到前面:视图];
}
}
}
同样,一旦我从这里回到这里,再看,它甚至没有画出路径
请帮忙
谢谢,显然,当您通过以下方式将贝塞尔路径添加到地图时:
[_mapView.layer addSublayer:shapeLayer];
它被添加到上面一些内部层,MKMapView
用来绘制注释。如果是,您将看到可以实现MKMapViewDelegate
协议,并在添加新电台注释时获得回调。发生这种情况时,您基本上会检查新添加注释的视图继承权,并在注释下方插入一个新的透明的UIView
layer。注意将所有注释放在这个透明的UIView
前面
// always remember to assign the delegate to get callbacks!
_mapView.delegate = self;
然后,不将形状层添加到\u 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/属性。我这样做了,现在我甚至看不到地图上绘制的图层。尽管它确实检查并显示了正确的注释。@Ashutosh,但这些信息确实不足以帮助您。上面有很多代码,我可以想象你会改变一些事情。您是否记得将pathOverlay
作为一个属性?在手册测试:
中,您是否阅读了代码,并注意到为了清晰起见,我删掉了您原始代码的一部分?还是你只是把整个方法都粘贴进去了?你是否按照我的建议更改了这些静态数据?在这一行:[parentView addSubview:pathOverlay]
,您可以停止在调试器中并确保parentView
不是nil吗?@Ashutosh,另外,您可能需要更新上面的问题,粘贴到您现在使用的代码中,以便我可以帮助调试。或者,如果你觉得问题变得太杂乱,就开始问一个新问题。您的呼叫。我注意到的另一件事是,当我清除并重新启动时,它会工作,下一次它完全工作正常。@Ashutosh,我现在没有时间详细查看您的新代码,但我可以告诉您,在我的示例应用程序中,每次滑动手势结束时,都会创建一个新的bezier路径来搜索内部,我将使用[\u mapView removeAnnotations:\u mapView.annotations]删除以前的所有管脚代码>
- (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;