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

Tim*_*ing 8 mkmapview mkannotation ios swift

我正在尝试为我的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

}
Run Code Online (Sandbox Code Playgroud)

Yuc*_*ong 17

制作自定义注释视图

没有公共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()
        }
    }
}    
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

其他说明

  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;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 由于title未设置注释的属性,因此您必须自己调用地图视图功能selectAnnotation.将以下内容添加到CustomAnnotationView类中:

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

如果您想在地图上有多个标记:

通常只是在初始化期间简单地绘制注释.在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
    }

}
Run Code Online (Sandbox Code Playgroud)

您可以在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
}
Run Code Online (Sandbox Code Playgroud)

最后请注意,有点令人困惑的是,如果你只是简单地将CustomAnnotationView的类从MKPinAnnotationView更改为MKAnnotationView,一切都是一样的,但它取代了"所有的pin"而不仅仅是注释.

  • 这是一个惊人的帖子.谢谢! (2认同)