5

私のアプリでは、ユーザーが地図上に図形を描画し、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];
        }
    }
}

また、私がこれから戻って表示し、再び来ると、パスを描画することさえありません。

助けてください。

ありがとう、

4

1 に答える 1

3

どうやら、次の方法でベジェパスをマップに追加すると、次のようになります。

        [_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;

偽のステーショングリッドでこれをテストしたところ、次の結果が得られました。

ここに画像の説明を入力してください

PS私はあなたのstatic変数を取り除くこともお勧めします。それらをクラスのivars/propertiesにするだけです。

于 2013-02-06T10:38:59.473 に答える