2013-02-05 30 views
5

Trong ứng dụng của tôi, người dùng vẽ một hình trên bản đồ và sử dụng UIBeizerPath tôi đang vẽ đường dẫn đó. Sau đó, dựa trên các tọa độ của đường dẫn tôi hiển thị các kết quả chỉ trong khu vực đó. Tất cả mọi thứ hoạt động tuyệt vời ngoại trừ bây giờ khi chú thích giảm trên bản đồ xem các chân trông giống như họ đang ở phía sau con đường có nghĩa là con đường trông ở phía trước.Làm thế nào để đưa UIBezierPath vào mặt sau của một đối tượng MKAnnotation?

Tôi đang sử dụng mã này để hiển thị các chú thích và đường dẫn:

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

Cũng một lần tôi quay trở lại từ này và xem và trở lại của nó thậm chí không vẽ Path.

Vui lòng trợ giúp.

Cảm ơn,

Trả lời

3

Rõ ràng, khi bạn thêm đường Bút chì của bạn vào bản đồ qua:

 [_mapView.layer addSublayer:shapeLayer]; 

nó là nhận được thêm trên một số lớp nội bộ mà MKMapView sử dụng để vẽ các chú thích. Nếu you take a look at this somewhat related question, bạn sẽ thấy rằng bạn có thể triển khai giao thức MKMapViewDelegate và nhận lại cuộc gọi lại khi thêm chú thích đài mới. Khi điều này xảy ra, về cơ bản bạn kiểm tra chế độ xem toàn bộ của các chú thích mới được thêm vào và chèn một chú thích mới, trong suốt UIView lớp bên dưới chúng. Bạn cẩn thận để đưa tất cả các chú thích ở phía trước của minh bạch này 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]; 
     } 
    } 
} 

Sau đó, thay vì thêm lớp hình dạng của bạn để _mapView.layer, bạn thêm nó vào lớp xem trong suốt của bạn, cũng sử dụng lớp mới này trong việc chuyển đổi toạ độ:

- (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 
     */    
    } 
} 

nơi tôi cũng đã thêm ivar (và thuộc tính) cho lớp trong suốt mới:

UIView* pathOverlay; 

Tôi đã thử nghiệm điều này với một mạng lưới các trạm giả và nhận được kết quả như sau:

enter image description here

T.B. Tôi cũng khuyên bạn nên loại bỏ các biến số static của mình. Chỉ cần làm cho họ ivars/tài sản của lớp học của bạn.

+0

Tôi đã làm điều này và bây giờ tôi thậm chí không thể nhìn thấy lớp được vẽ trên Bản đồ. Mặc dù nó kiểm tra chú thích chính xác và hiển thị chúng. – Ashutosh

+0

@Ashutosh, Đó thực sự không đủ thông tin để giúp bạn. Có rất nhiều mã ở trên, và có một vài điều tôi có thể tưởng tượng bạn đang thay đổi. Bạn có nhớ đặt 'pathOverlay' thành thuộc tính không? Trong 'handleGesture:', bạn đã đọc mã, lưu ý rằng tôi cắt ra các phần của mã ban đầu của bạn, cho rõ ràng? Hay bạn vừa dán toàn bộ phương pháp? Bạn đã thay đổi những thống kê như tôi đề nghị? Tại dòng này: '[parentView addSubview: pathOverlay];', bạn có thể dừng lại trong trình gỡ lỗi và đảm bảo 'parentView' không phải là không? – Nate

+0

@Ashutosh, cũng có thể chỉ cần bạn cập nhật câu hỏi ở trên, dán vào mã bạn đang sử dụng ** ngay bây giờ **, vì vậy tôi có thể giúp gỡ lỗi. Hoặc bắt đầu một câu hỏi mới nếu bạn nghĩ rằng nó quá lộn xộn. Cuộc gọi của bạn. – Nate

Các vấn đề liên quan