gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 04:44:24 26 4
gpt4 key购买 nike

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

我正在使用这段代码来显示注释和路径:

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

此外,一旦我从这里返回并查看并再次出现,它甚至没有绘制路径。

请帮忙。

谢谢,

最佳答案

显然,当您通过以下方式将贝塞尔路径添加到 map 时:

        [_mapView.layer addSublayer:shapeLayer];

它被添加到之上一些MKMapView用来绘制注释的内部层。如果you take a look at this somewhat related question ,您会看到您可以实现 MKMapViewDelegate 协议(protocol),并在添加新站点注释时获得回调。发生这种情况时,您基本上会检查新添加的注释的 View 层次结构,并在它们下方 插入一个新的透明 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,而是将其添加到透明 View 层,同时在坐标转换中使用这个新层:

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

我用伪造的站点网格对此进行了测试,得到了以下结果:

enter image description here

附言我还建议摆脱您的 static 变量。只需将它们设为您类(class)的 ivars/属性即可。

关于ios - 如何将 UIBezierPath 带到 MKAnnotation 对象的后面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14714374/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com