如何修改MKMapView中被选中annotation标注的颜色
解决方案
核心逻辑
MKMarkerAnnotationView 没有内置selectedGlyphTintColor属性,我们可以通过监听选中状态手动切换glyphTintColor实现需求,有两种常见实现方案:
方案1:使用MKMapView选中代理实现(改动最小)
直接实现MKMapView的选中/取消选中代理方法,在状态变化时修改颜色,你手动调用selectAnnotation方法也会自动触发该代理:
// 选中annotation时调用 func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { guard let markerView = view as? MKMarkerAnnotationView else { return } // 替换为你需要的选中状态颜色 markerView.glyphTintColor = .red } // 取消选中annotation时调用 func mapView(_ mapView: MKMapView, didDeselect view: MKAnnotationView) { guard let markerView = view as? MKMarkerAnnotationView else { return } // 恢复为默认未选中颜色 markerView.glyphTintColor = Constant.Colors.secondaryMainColor }
如果不想用代理,也可以直接在你现有选中逻辑中修改,在mapView.selectAnnotation(i, animated: true)后补充以下代码:
// 先恢复上一个选中的标注颜色 if let oldAnnotation = annotationForCollectionView, let oldView = mapView.view(for: oldAnnotation) as? MKMarkerAnnotationView { oldView.glyphTintColor = Constant.Colors.secondaryMainColor } // 修改当前选中标注的颜色 if let currentView = mapView.view(for: i) as? MKMarkerAnnotationView { currentView.glyphTintColor = .red // 替换为选中色 }
方案2:自定义标注子类实现(状态管理更稳妥)
如果需要多处使用选中颜色切换逻辑,推荐自定义MKMarkerAnnotationView子类,自动管理状态:
- 定义自定义子类
class CustomMarkerAnnotationView: MKMarkerAnnotationView { // 配置普通状态和选中状态的颜色 var normalTintColor: UIColor = Constant.Colors.secondaryMainColor var selectedTintColor: UIColor = .red override var isSelected: Bool { didSet { // 状态变化时自动切换颜色 glyphTintColor = isSelected ? selectedTintColor : normalTintColor } } }
- 修改
viewFor annotation方法中的实现
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { // 替换为自定义子类 let annotationView = CustomMarkerAnnotationView(annotation: annotation, reuseIdentifier: "MyMarker") annotationView.markerTintColor = .clear annotationView.glyphImage = UIImage(named: "MapIcon") return annotationView }
额外优化建议
你当前代码中直接用==判断经纬度浮点数相等,存在精度误差导致匹配失败的风险,推荐改为距离判断:
let markerLocation = CLLocation(latitude: marker.latitude, longitude: marker.longitude) let targetLocation = CLLocation(latitude: scrollableElement.latitude, longitude: scrollableElement.longitude) // 距离小于1米视为同一个标注 if markerLocation.distance(from: targetLocation) < 1 { // 原有选中逻辑 }
内容的提问来源于stack exchange,提问作者Ice
相关产品推荐
相关产品推荐

