如何为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
相关产品推荐
相关产品推荐

