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

s3fp2yjn  于 2022-11-26  发布在  iOS
关注(0)|答案(2)|浏览(166)

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

}
3z6pesqy

3z6pesqy1#

创建自定义注解视图

没有公共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()
        }
    }
}

其他备注

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;
}

1.由于没有设置注解的title属性,因此您必须自己调用Map视图函数selectAnnotation。将以下内容添加到CustomAnnotationView类:

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

如果您希望在Map上有多个标记:
在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,则一切工作都是一样的,但它会替换“所有引脚”,而不仅仅是注解。

xmd2e60i

xmd2e60i2#

更新了最新swift的代码。这是MKPinAnnotationView的新子类,您可以复制粘贴以进行测试:

import UIKit
import MapKit

class CustomAnnotationView : MKPinAnnotationView
{
    let selectedLabel:UILabel = UILabel.init(frame:CGRect(x:0, y:0, width:140, height: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.gray
            selectedLabel.layer.borderColor = UIColor.darkGray.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()
        }
    }
}

相关问题