viewForAnnotation 有时无法获取自定义 MKAnnotation class 并正确呈现它

viewForAnnotation sometimes can't get custom MKAnnotation class and render it properly

我有不同的 classes (MKAnnotation subclass) 表示地图注释。
我将它们加载到地图上,一切正常,但是当我移动或缩放地图图钉时,它们的图像开始丢失。
当我调用 pan map viewForAnnotation 时,例如 BluePin class 的 pin 不再进入它的 if 块,结果它呈现来自 viewForAnnotation 带有默认图钉图像(绿色)。

更新

我刚刚意识到代码实际上正确地进入了每个 IF 但从未进入嵌套 IF 所以这行代码会产生一些问题:

var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("blue")
            if (annotationView == nil) { ... after zoom/pan never get here }...

这里可能是什么问题:

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

        if annotation is MKUserLocation {            
            return nil
        }
if(annotation.isKindOfClass(BluePin)){

            var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("blue")
            if (annotationView == nil) {
                annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "blue")
                annotationView.canShowCallout = true;

                annotationView.image = UIImage(named: "blue")

                return annotationView
            }
        } else if(annotation.isKindOfClass(RedPin)){

            var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("red")
            if (annotationView == nil) {
                annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "red")
                annotationView.canShowCallout = true;                                
                annotationView.image = UIImage(named: "red")

                return annotationView
            }
        }


            var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier("def") as? MKPinAnnotationView
            if pinView == nil {
                pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "def")                
                pinView!.pinColor = .Green

            }
            else {
                pinView!.annotation = annotation
            }

            return pinView
    }

dequeueReusableAnnotationViewWithIdentifier 方法将 return 当前未用于显示的先前创建的视图(如果有)(这是使用此方法的全部意义,以便您获得视图重复使用)。

当该方法找到可以重复使用的视图时,它将 return 该视图,因此结果将是非 nil

当您 zoom/pan 地图时,一些注释从视图中消失,新的注释出现。进入视图的那些现在可以重新使用不再可见的注释视图。所以 dequeueReusableAnnotationViewWithIdentifier return 是一个非 nil 结果。

当前代码未处理 dequeueReusableAnnotationViewWithIdentifier return 非 nil 蓝色和红色引脚的情况,因此 执行继续大 if 之后的下一条语句是 var pinView = mapView...,然后创建默认的绿色图钉视图。

需要修改代码以处理 dequeueReusableAnnotationViewWithIdentifier return 非 nil 蓝色和红色引脚的情况:

    if(annotation.isKindOfClass(BluePin)) {
        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("blue")
        if (annotationView == nil) {
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "blue")
            annotationView.canShowCallout = true;
            annotationView.image = UIImage(named: "blue")
        } else {
            //handle blue view re-use...
            annotationView.annotation = annotation
        }

        //move return to after the if-else...
        return annotationView
    }
    else if(annotation.isKindOfClass(RedPin)) {

        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("red")
        if (annotationView == nil) {
            annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "red")
            annotationView.canShowCallout = true;
            annotationView.image = UIImage(named: "red")
        } else {
            //handle red view re-use...
            annotationView.annotation = annotation
        }

        //move return to after the if-else...
        return annotationView
    }