这是我的代码。我想添加自己的自定义标注视图而不是iOS默认值。我知道只有左侧标注和右侧标注视图,但我需要添加一个带有我自己的背景和标签的视图工具提示类型。
- (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;
}
}
答案 0 :(得分:131)
我遇到了同样的问题并最终做了以下事情:
当我收到mapView委托回调
时-(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 取决于您的需求)
mapView委托中的2)
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
使用您的子类而不是MKAnnotationView / MKPinAnnotationView
您的子类.m文件中的3)会覆盖以下两种方法:
- (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;
}
全部完成!
答案 1 :(得分:10)
答案 2 :(得分:2)
以上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
}
答案 3 :(得分:1)
以下是CallOut View的最佳示例
http://www.cocoacontrols.com/platforms/ios/controls/gikanimatedcallout
http://www.cocoacontrols.com/platforms/ios/controls/multirowcalloutannotationview
答案 4 :(得分:1)
我刚为地图视图创建了一个自定义标注,可以避免在点按时标注消失的问题。 Here是我采取的步骤的要点。
答案 5 :(得分:0)