自定义MKAnnotation标注视图?

我有一个MKPointAnnotation

 let ann = MKPointAnnotation() self.ann.coordinate = annLoc self.ann.title = "Customize me" self.ann.subtitle = "???" self.mapView.addAnnotation(ann) 

它看起来像这样:

在这里输入图像说明

我如何定制这个标注视图来创build我自己的视图,而不是预定义视图?

首先应该注意的是,只需调整系统提供的标注的属性即可启用对标注的最简单更改,但可以通过rightCalloutAccessoryViewleftCalloutAccessoryView定制右侧和左侧附件。 您可以在viewForAnnotation执行该configuration。

在iOS 9中,我们现在可以访问detailCalloutAccessoryView ,它可以用潜在的视觉丰富的视图replace标注的副标题,同时仍然享受标注泡泡的自动翻版(使用自动布局使这更容易)。

例如,以下是一个标注,使用MKSnapshotter为WWDC 2015video中的详细说明附件中的图像视图提供图像。MapKit中的新增function :

在这里输入图像说明

你可以用这样的东西做到这一点:

 func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { if annotation is MKUserLocation { return nil } let identifier = "MyCustomAnnotation" var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) if annotationView == nil { annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) annotationView?.canShowCallout = true } else { annotationView!.annotation = annotation } configureDetailView(annotationView!) return annotationView } func configureDetailView(annotationView: MKAnnotationView) { let width = 300 let height = 200 let snapshotView = UIView() let views = ["snapshotView": snapshotView] snapshotView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[snapshotView(300)]", options: [], metrics: nil, views: views)) snapshotView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[snapshotView(200)]", options: [], metrics: nil, views: views)) let options = MKMapSnapshotOptions() options.size = CGSize(width: width, height: height) options.mapType = .SatelliteFlyover options.camera = MKMapCamera(lookingAtCenterCoordinate: annotationView.annotation!.coordinate, fromDistance: 250, pitch: 65, heading: 0) let snapshotter = MKMapSnapshotter(options: options) snapshotter.startWithCompletionHandler { snapshot, error in if snapshot != nil { let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height)) imageView.image = snapshot!.image snapshotView.addSubview(imageView) } } annotationView.detailCalloutAccessoryView = snapshotView } 

如果您正在寻找对标注进行更为激进的重新devise,或者需要支持9之前的iOS版本,则需要更多工作。 该过程需要(a)禁用默认标注; 和(b)当用户点击现有的注解视图(即地图上的视觉针)时添加自己的视图。

然后复杂的标注的devise,你必须画出你想要的一切。 例如,如果你想画出一个泡泡来产生呼出的popup式感觉,你必须自己做。 但是,对于如何绘制形状,图像,文本等有一定的了解,您应该能够渲染出符合所需UX的标注:

自定义标注

只需将该视图添加为注释视图本身的子视图,并相应地调整其约束:

 func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) { let calloutView = ... calloutView.translatesAutoresizingMaskIntoConstraints = false calloutView.backgroundColor = UIColor.lightGrayColor() view.addSubview(calloutView) NSLayoutConstraint.activateConstraints([ calloutView.bottomAnchor.constraintEqualToAnchor(view.topAnchor, constant: 0), calloutView.widthAnchor.constraintEqualToConstant(60), calloutView.heightAnchor.constraintEqualToConstant(30), calloutView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor, constant: view.calloutOffset.x) ]) } 

有关创build您自己的标注视图的示例,请参阅https://github.com/robertmryan/CustomMapViewAnnotationCalloutSwift 。 这只添加了两个标签,但它说明了一个事实,即您可以绘制任意形状的泡泡,使用约束来指定标注的大小等。

用classtype MKAnnotationView创buildcocoa文件

CustomeAnnotationView.h文件

 @interface CustomeAnnotationView : MKAnnotationView @property (strong, nonatomic) UIButton *buttonCustomeCallOut; - (void)setSelected:(BOOL)selected animated:(BOOL)animated; @end 

CustomeAnnotationView.m文件

 @implementation CustomeAnnotationView -(id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code } return self; } - (void)setSelected:(BOOL)selected animated:(BOOL)animated{ [super setSelected:selected animated:animated]; if(selected) { self.buttonCustomeCallOut = [UIButton buttonWithType:UIButtonTypeCustom];//iconShare//iconShareBlue [self.buttonCustomeCallOut addTarget:self action:@selector(buttonHandlerCallOut:) forControlEvents:UIControlEventTouchDown]; [self.buttonCustomeCallOut setBackgroundColor:[UIColor blueColor]]; [self.buttonCustomeCallOut setFrame:CGRectMake(-40,-80, 100, 100)]; [self addSubview:self.buttonCustomeCallOut]; [self.buttonCustomeCallOut setUserInteractionEnabled:YES]; } else { //Remove your custom view... [self.buttonCustomeCallOut setUserInteractionEnabled:NO]; [self.buttonCustomeCallOut removeFromSuperview]; self.buttonCustomeCallOut=nil; } } -(void)buttonHandlerCallOut:(UIButton*)sender{ NSLog(@"Annotation Clicked"); } - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event { UIView* v = [super hitTest:point withEvent:event]; if (v != nil) { [self.superview bringSubviewToFront:self]; } return v; } - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event { CGRect rec = self.bounds; BOOL isIn = CGRectContainsPoint(rec, point); if(!isIn) { for (UIView *v in self.subviews) { isIn = CGRectContainsPoint(v.frame, point); if(isIn) break; } } return isIn; } @end 

把这个代码放在你想创buildcustome调用的地方

 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { static NSString *identifier = @"CustAnnotation"; CustomeAnnotationView *annotationView = (CustomeAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; if (annotationView == nil) { annotationView = [[CustomeAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier]; } annotationView.enabled = YES; annotationView.canShowCallout = NO; annotationView.centerOffset = CGPointMake(0,-10);//-18 return annotationView; }