iOS 中 annotationView 中的自定义 pin 图像
Posted
技术标签:
【中文标题】iOS 中 annotationView 中的自定义 pin 图像【英文标题】:Custom pin image in annotationView in iOS 【发布时间】:2015-12-26 16:44:15 【问题描述】:我正在尝试从 Swift 1.2 更改为 Swift 2.0,并且我已完成更改。目前我正在对 MapViewController 进行更改,没有任何错误或警告,但我的 pin (annotationView) 的自定义图像未分配给 pin,它显示的是默认图像(红点)。
这是我的代码,我希望你能给我一些提示,因为我认为一切都很好,但它仍然无法正常工作:
func parseJsonData(data: NSData) -> [Farmacia]
let farmacias = [Farmacia]()
do
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
// Parse JSON data
let jsonProductos = jsonResult?["farmacias"] as! [AnyObject]
for jsonProducto in jsonProductos
let farmacia = Farmacia()
farmacia.id = jsonProducto["id"] as! String
farmacia.nombre = jsonProducto["nombre"] as! String
farmacia.location = jsonProducto["location"] as! String
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(farmacia.location, completionHandler: placemarks, error in
if error != nil
print(error)
return
if placemarks != nil && placemarks!.count > 0
let placemark = placemarks?[0]
// Add Annotation
let annotation = MKPointAnnotation()
annotation.title = farmacia.nombre
annotation.subtitle = farmacia.id
annotation.coordinate = placemark!.location!.coordinate
self.mapView.addAnnotation(annotation)
)
catch let parseError
print(parseError)
return farmacias
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
let identifier = "MyPin"
if annotation.isKindOfClass(MKUserLocation)
return nil
// Reuse the annotation if possible
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
if annotationView == nil
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView!.canShowCallout = true
annotationView!.image = UIImage(named: "custom_pin.png")
let detailButton: UIButton = UIButton(type: UIButtonType.DetailDisclosure)
annotationView!.rightCalloutAccessoryView = detailButton
print(annotationView!.image)
return annotationView
提前致谢,
问候。
【问题讨论】:
【参考方案1】:接受的答案不起作用,因为它在 else
块中未初始化 annotationView
。
这里有一个更好的解决方案。如果可能,它会使注释视图出队,否则会创建一个新视图:
// https://***.com/a/38159048/1321917
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
// Don't want to show a custom image if the annotation is the user's location.
guard !(annotation is MKUserLocation) else
return nil
// Better to make this class property
let annotationIdentifier = "AnnotationIdentifier"
var annotationView: MKAnnotationView?
if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier)
annotationView = dequeuedAnnotationView
annotationView?.annotation = annotation
else
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
annotationView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
if let annotationView = annotationView
// Configure your annotation view here
annotationView.canShowCallout = true
annotationView.image = UIImage(named: "yourImage")
return annotationView
【讨论】:
这对我的帮助远远超过接受的答案,非常感谢@Andrey Gordeev 哇!这严重救了我!!!我遇到了一些严重的性能问题,但是看到这个关于如何正确使用标识符的示例确实很有帮助。我以为我一开始也正确使用它。这应该是公认的答案! 太棒了!谢谢。 如果在声明“annotationView”时出列,实际上可以使这更简单。看我的回答。【参考方案2】:答案如下:
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
let identifier = "MyPin"
if annotation.isKindOfClass(MKUserLocation)
return nil
let detailButton: UIButton = UIButton(type: UIButtonType.DetailDisclosure)
if let annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "pin")
annotationView.canShowCallout = true
annotationView.image = UIImage(named: "custom_pin.png")
annotationView.rightCalloutAccessoryView = detailButton
else
annotationView.annotation = annotation
return annotationView
问候
【讨论】:
感谢您分享您的解决方案。它也帮助了我 投了反对票。 1)“annotationView”实例是在 if-let 范围内创建的,并且在 else-范围内不存在。 2)如果您成功地可以使注释视图出队,那么您应该使用它而不是创建一个新实例。新实例应在 else 范围内创建,其中不能将可重用对象出列。 我认为需要 MKPinAnnotation 作为 MKAnnotation 的子级【参考方案3】:SWIFT 3,4
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
if annotation.isKind(of: MKUserLocation.self)
return nil
let annotationIdentifier = "AnnotationIdentifier"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier)
if (pinView == nil)
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
pinView?.canShowCallout = false
return pinView
【讨论】:
以上是关于iOS 中 annotationView 中的自定义 pin 图像的主要内容,如果未能解决你的问题,请参考以下文章
mkmapview MKUserLocation AnnotationView
点击相应的annotationview后如何在mkannotationview中实现字幕的更新