如何在地图的Annotation标注中添加自定义视图
这是我的代码我想添加我自己的自定义标注视图,而不是ios默认情况下,我知道只有leftCallout和右标注视图,但我需要添加一个视图工具提示types与我自己的背景和标签
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { MKAnnotationView *userAnnotationView = nil; if ([annotation isKindOfClass:MKUserLocation.class]) { userAnnotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"UserLocation"]; if (userAnnotationView == nil) { userAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"UserLocation"]; } else userAnnotationView.annotation = annotation; userAnnotationView.enabled = YES; userAnnotationView.canShowCallout = YES; userAnnotationView.image = [UIImage imageNamed:@"map_pin.png"]; UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0,0,141,108)]; view.backgroundColor = [UIColor clearColor]; UIImageView *imgView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"toltip.png"]]; [view addSubview:imgView]; userAnnotationView.leftCalloutAccessoryView = view; return userAnnotationView; } }
我有同样的问题,最终做了以下事情:
当我收到mapView委托callback
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
(现在是我想要显示自定义CalloutView的时候了)
我使用收到的视图作为参数*(MKAnnotationView )视图 (这是一个针视图),只需将我的自定义视图添加到该视图使用
[view addSubview:customView];
它将在该视图顶部添加自定义视图,所以如果我们希望它在上面的视图,我们必须改变自定义视图中心属性,如下所示:
CGRect customViewRect = customView.frame; CGRect rect = CGRectMake(-customViewRect.size.width/2, -customViewRect.size.height-7, customViewRect.size.width, customViewRect.size.height); customView.frame = rect; [view addSubview:customView];
就我而言,它看起来像这样
!注意 :
有一个警告,但是可以很容易地修复,你的自定义视图将忽略触摸事件 ,因为mapView与触摸不同。 这是一个快速修复 :
1)子类MKAnnotationView (或MKPinAnnotationView取决于你需要什么)
2)在你的mapView委托
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
使用你的子类而不是MKAnnotationView / MKPinAnnotationView
3)在你的子类.m文件中覆盖两个方法如下:
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event { UIView* hitView = [super hitTest:point withEvent:event]; if (hitView != nil) { [self.superview bringSubviewToFront:self]; } return hitView; } - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event { CGRect rect = self.bounds; BOOL isInside = CGRectContainsPoint(rect, point); if(!isInside) { for (UIView *view in self.subviews) { isInside = CGRectContainsPoint(view.frame, point); if(isInside) break; } } return isInside; }
全做完了!
我创build了一个库来显示自定义标注。
DXCustomCallout-ObjC
您可以传递任何自定义视图的标注! 它也支持UIControls的事件。
上面的Swift中的最佳答案
这可以节省一些时间来重写自己。
!注意:
有一个警告,但是可以很容易地修复,你的自定义视图将忽略触摸事件,因为mapView与触摸不同。 这是一个快速修复:
1)子类MKAnnotationView(或MKPinAnnotationView取决于你需要什么)
2)在你的mapView委托
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
使用你的子类而不是MKAnnotationView / MKPinAnnotationView
3)在你的子类.m文件中覆盖两个方法如下:
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { let hitView = super.hitTest(point, withEvent: event) if (hitView != nil) { self.superview?.bringSubviewToFront(self) } return hitView; } override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool { let rect = self.bounds var isInside = CGRectContainsPoint(rect, point) if(!isInside) { for view in self.subviews { isInside = CGRectContainsPoint(view.frame, point) break; } } return isInside }
这里是CallOut View的最佳例子
http://www.cocoacontrols.com/platforms/ios/controls/gikanimatedcallout
http://www.cocoacontrols.com/platforms/ios/controls/multirowcalloutannotationview
我刚刚为我的地图视图创build了一个自定义标注,以避免点击时标注消失的问题。 这是我采取的步骤与Gist。