【问题标题】:Custom pin image in annotationView in iOSiOS 中 annotationView 中的自定义 pin 图像
【发布时间】: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
}

提前致谢,

问候。

【问题讨论】:

    标签: ios swift mkmapview mkannotationview


    【解决方案1】:

    接受的答案不起作用,因为它在 else 块中未初始化 annotationView

    这里有一个更好的解决方案。如果可能,它会使注释视图出队,否则会创建一个新视图:

    // https://stackoverflow.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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 2013-05-23
      • 1970-01-01
      相关资源
      最近更新 更多