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

时间:2015-01-21 18:50:57

标签: ios swift mkmapview mkannotation

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

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

最后,我希望有完全自定义的标注气泡,每个针脚都有单独的标签。所以我真正需要知道的是在创建注释时如何访问viewForAnnotation委托以更改每个引脚的属性。

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

}

1 个答案:

答案 0 :(得分:14)

制作自定义注释视图

没有公共API允许您直接访问弹出窗口中的标签。您需要做的是创建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()
        }
    }
}    

enter image description here

其他注释

  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)
    }
    
  3. 如果您想在地图上添加多个标记:

    通常只是在初始化期间简单地绘制注释。在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中为每个注释设置字符串(或其他值 - 例如面板的颜色)。这就像在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,一切都可以正常工作,但它会替换“所有引脚”而不仅仅是注释。