You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为MKAnnotation设置个性化glyphtext以显示自定义identifier

问题描述

我想创建MKPointAnnotation,让标注覆盖层显示自定义的identifier编号(比如第一个显示1、第二个显示2),而不是默认的大头针样式。我已经通过UILongPressGestureRecognizer给mapView添加标注,创建了CustomAnnotation类继承自MKPointAnnotation并扩展了identifier属性,长按触发时会给这个属性赋值。但现在在mapView(_:viewFor:)代理方法里设置标注样式时,没法把每个标注的identifier赋值给annotationView.glyphText。

相关代码如下:

自定义Annotation类

class CustomAnnotation: MKPointAnnotation {
    var identifier: Int!
}

长按手势中设置identifier的代码

let annotation = CustomAnnotation()
annotation.identifier = mapView.annotations.count

代理方法代码

extension ViewController: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        guard annotation is CustomAnnotation else { return nil }

        let annotationView = MKMarkerAnnotationView()
        annotationView.glyphTintColor = .white
        annotationView.glyphText = "44"
            
        return annotationView
    }
}
解决方案

你现在的核心问题是:代理方法里只判断了annotation是CustomAnnotation类型,但没做类型转换,所以根本访问不到identifier属性。另外直接创建MKMarkerAnnotationView没有复用,性能也不好,建议加上复用池优化。

修改后的代理方法代码如下:

extension ViewController: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        // 先把annotation转成自定义的CustomAnnotation类型,同时过滤系统的用户位置标注
        guard let customAnnotation = annotation as? CustomAnnotation else {
            if annotation is MKUserLocation {
                return nil // 让系统处理用户位置标注
            }
            return nil
        }
        
        // 复用标注视图,避免重复创建
        let reuseID = "CustomMarker"
        let annotationView: MKMarkerAnnotationView
        
        if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseID) as? MKMarkerAnnotationView {
            annotationView = dequeuedView
            annotationView.annotation = customAnnotation
            annotationView.glyphText = nil // 重置原有内容
        } else {
            annotationView = MKMarkerAnnotationView(annotation: customAnnotation, reuseIdentifier: reuseID)
            annotationView.glyphTintColor = .white
            annotationView.markerTintColor = .systemBlue // 可以自定义标注颜色
        }
        
        // 把identifier转成字符串赋值给glyphText
        annotationView.glyphText = "\(customAnnotation.identifier)"
        
        return annotationView
    }
}

另外还有个小坑:你用mapView.annotations.count作为identifier,如果地图开启了用户位置显示,annotations里会包含MKUserLocation,导致第一个标注的编号是1而不是0。建议单独维护一个计数器:

// 在ViewController里定义一个实例变量
private var annotationCounter = 1

// 长按手势里的代码改成这样
let annotation = CustomAnnotation()
annotation.identifier = annotationCounter
annotationCounter += 1
mapView.addAnnotation(annotation)

这样就能保证第一个标注显示1,第二个显示2,完全符合你的需求。

内容的提问来源于stack exchange,提问作者m_s

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 13:52:48