如何根据数组指定变量为Map View Controller设置自定义annotation
问题原因
- 你现在用系统默认的
MKPointAnnotation存标注信息,没有把自定义的color字段绑定到对应标注上,代理方法里拿到的annotation根本没有颜色信息,你遍历数组直接返回第一个匹配项的逻辑完全错误,当然显示不对。 - 完全不需要自己维护
annotationView数组,MapKit自带的复用池机制已经能满足需求,自己维护反而容易出内存和复用混乱的问题。 - 你的现有代码还有不少语法错误:比如
UIImage(named: "Red)少了右引号、数组下标写了大写的I、返回annotationView()多了括号、addAnnotations方法缺了func声明等等,也会导致功能异常。
修正方案
1. 自定义Annotation类,继承MKPointAnnotation
不要用struct,直接继承系统的标注类,把需要的属性带上:
class CustomAnnotation: MKPointAnnotation { var color: String? }
2. 修改添加标注的逻辑
添加标注的时候直接用自定义的类,把颜色信息存进去:
// 添加标注方法 func addAnnotations() { guard !annotationArray.isEmpty else { return } for item in annotationArray { let annotation = CustomAnnotation() annotation.title = item.name annotation.coordinate = item.coordinates ?? CLLocationCoordinate2D(latitude: 0, longitude: 0) annotation.color = item.color // 把颜色绑定到当前标注上 mapView.addAnnotation(annotation) } }
3. 重写viewFor代理逻辑
不需要遍历数组,直接拿到当前处理的标注的颜色属性设置图片即可:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { // 过滤用户位置标注 guard !(annotation is MKUserLocation) else { return nil } // 复用annotationView let reuseId = "CustomAnnotationView" var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) if annotationView == nil { annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId) annotationView?.canShowCallout = true } else { annotationView?.annotation = annotation // 复用的时候要更新绑定的annotation } // 拿到当前标注的颜色设置图片 if let customAnnotation = annotation as? CustomAnnotation { switch customAnnotation.color { case "Blue": annotationView?.image = UIImage(named: "Blue")?.transformToMapAnnotation() case "Red": annotationView?.image = UIImage(named: "Red")?.transformToMapAnnotation() default: // 可以加个默认图片兜底 annotationView?.image = UIImage(named: "Default")?.transformToMapAnnotation() } } return annotationView }
内容的提问来源于stack exchange,提问作者WhySoSerious33
相关产品推荐
相关产品推荐

