Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何将UIBezierPath带到MKAnnotation对象的后面?_Ios_Objective C_Mkmapview_Uibezierpath - Fatal编程技术网

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

Ios 如何将UIBezierPath带到MKAnnotation对象的后面?,ios,objective-c,mkmapview,uibezierpath,Ios,Objective C,Mkmapview,Uibezierpath,在我的应用程序中,用户在地图上绘制一个形状,并使用UIBeizerPath绘制该路径。然后根据路径的坐标,我显示的结果仅在该区域。一切都很好,只是现在当注释掉在地图视图上时,针脚看起来像在路径后面,这意味着路径看起来在前面 我使用以下代码显示注释和路径: -(void)clearAnnotationAndPath:(id)sender { [_mapView removeAnnotations:_mapView.annotations]; path = [UIBezierPat

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

我使用以下代码显示注释和路径:

 -(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;