Swift – 自定义MKAnnotationView,设置标签标题

我正在尝试为我的mapView标注气泡自定义MKAnnotationView。 我可以在创build注解时设置注解标题,还可以自定义MKAnnotationView以添加标签或图像等(在viewForAnnotation委托中),但是如何更改在viewForAnnotation委托中创build的标签,以便标题每个引脚是不同的?

我遇到的另一个问题是,如果在viewDidLoad方法中创build标题或副标题时没有添加标题或副标题,但是我仍然尝试通过离开self.map.addAnnotation(annotation)创build一个标题或副标题,当我运行该应用程序,并点击引脚没有标注泡沫显示。

最后,我想完全定制标注泡泡,每个针脚都有单独的标签。 所以我真正需要知道的是如何在创build注解时访问viewForAnnotation委托来改变每个pin的属性。

 override func viewDidLoad() { super.viewDidLoad() var countries: [String] = ["Germany","Germany","Poland","Denmark"] var practiceRoute: [CLLocationCoordinate2D] = [CLLocationCoordinate2DMake(50, 10),CLLocationCoordinate2DMake(52, 9),CLLocationCoordinate2DMake(53, 20),CLLocationCoordinate2DMake(56, 14)] for vari=0; i<practiceRoute.count; i++ { var annotation = MKPointAnnotation annotation.title = countries[i] annotation.coordinate = practiceRoute[i] self.map.addAnnotation(annotation) } } func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! { if annotation is MKUserLocation { return nil } let reuseId = "pin" var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView if(pinView==nil){ pinView=MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId) pinView!.canShowCallout = true let base = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 50)) base.backgroundColor = UIColor.lightGrayColor() let label1 = UILabel(frame: CGRect(x: 30, y: 10, width: 60, height: 15)) label1.textColor = UIColor.blackColor() label1.text = "12 photos" base.addSubview(label1) pinView!.leftCalloutAccessoryView = base pinView!.pinColor = .Red } return pinView } 

制作您的自定义注释视图

没有公共API允许您直接访问popup的标签。 你需要做的是做一个MKPinAnnotationView的子类,并做任何你想要的定制。 举个例子,

 class CustomAnnotationView : MKPinAnnotationView { let selectedLabel:UILabel = UILabel.init(frame:CGRectMake(0, 0, 140, 38)) override func setSelected(selected: Bool, animated: Bool) { super.setSelected(false, animated: animated) if(selected) { // Do customization, for example: selectedLabel.text = "Hello World!!" selectedLabel.textAlignment = .Center selectedLabel.font = UIFont.init(name: "HelveticaBold", size: 15) selectedLabel.backgroundColor = UIColor.lightGrayColor() selectedLabel.layer.borderColor = UIColor.darkGrayColor().CGColor selectedLabel.layer.borderWidth = 2 selectedLabel.layer.cornerRadius = 5 selectedLabel.layer.masksToBounds = true selectedLabel.center.x = 0.5 * self.frame.size.width; selectedLabel.center.y = -0.5 * selectedLabel.frame.height; self.addSubview(selectedLabel) } else { selectedLabel.removeFromSuperview() } } } 

在这里输入图像说明

其他说明

  1. 在地图视图中使用此自定义视图:

     func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { var anno = mapView.dequeueReusableAnnotationViewWithIdentifier("Anno") if anno == nil { anno = CustomAnnotationView.init(annotation: annotation, reuseIdentifier: "Anno") } return anno; } 
  2. 由于没有设置注释的title属性,所以您必须自己调用地图视图函数selectAnnotation 。 将以下内容添加到CustomAnnotationView类中:

     override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { mapView?.selectAnnotation(self.annotation!, animated: true) } 

如果你想在地图上有多个标记,

通常只需在初始化过程中绘制注释。 在setSelected中只返回false(意思是“始终显示所有注释”)。

 class DotAnnotationView : MKPinAnnotationView { let dot: UILabel = UILabel.init(frame:CGRect(x: 0, y: 0, width: 20, height: 20)) required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) _setup() } override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) _setup() } override func prepareForReuse() { dot.text = "you forgot to set the text value?" } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(false, animated: animated) } func _setup() { dot.textAlignment = .center .. etc } } 

您可以为mapView#viewFor中的每个注释设置string(或其他值 – 表示面板的颜色)。 这就像在UITableView中填充单元格一样。

 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { let textForThisItem = annotation.title!! // or, just use index#of to determine which row this is in your data array if annotation.isEqual(mkMap.userLocation) { // skip the user-position indicator return nil } var anno = mapView.dequeueReusableAnnotationView(withIdentifier: "anno") if anno == nil { anno = DotAnnotationView.init(annotation: annotation, reuseIdentifier: "anno") } (anno as! DotAnnotationView).dot.text = textForThisItem return anno } 

最后要注意的是,如果你非常简单地将CustomAnnotationView的类从MKPinAnnotationView更改为MKAnnotationView,那么所有的工作原理都是一样的,但它将replace“所有的引脚”而不仅仅是注释。