0
votes

Problème de réutilisable mkannotationview pour montrer des images distinctes

Je montre 3 annotations distinctes sur une carte. Pour aller faire cela, j'ai une variable de classe qui indique la valeur actuelle du nom d'image à définir dans la propriété MkannotationView. J'ai sous-classée mkannotationview pour endormir une variable de classe pour obtenir le nom de l'image en cas de réutilisation de l'annotation.

Le problème est que lorsque je traîne la carte, laissant les annotations en dehors de la vue et quand je le fais glisser pour voir les annotations, ces Demandez à leurs images échangées. p>

My Enum et MkannotationView Classe: P>

 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        
        guard !(annotation is MKUserLocation) else {
            return nil
        }
        
        let identifier = "Custom annotation"
        
        var annotationView: MyMKAnnotationView?
        
        guard let dequeuedAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MyMKAnnotationView else {
            let av = MyMKAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView = av
            annotationView?.annotation = annotation
            annotationView?.canShowCallout = true
            annotationView?.translatesAutoresizingMaskIntoConstraints = false
            annotationView?.widthAnchor.constraint(equalToConstant: 35).isActive = true
            annotationView?.heightAnchor.constraint(equalToConstant: 35).isActive = true
            annotationView?.iconType = annotationIcon.rawValue //AnnotationIcon enum class variable
            annotationView?.image = UIImage(named: annotationView?.iconType ?? "")
            
            return av
        }
        annotationView = dequeuedAnnotationView
        annotationView?.image = UIImage(named: annotationView?.iconType ?? "")
        
        return annotationView
    }


1 commentaires

Vérification de l'adresse mémoire de la MKANnotationView, ils sont déplacés sur la carte. Ne pas échanger leurs images.


3 Réponses :


1
votes

Avant de réutiliser le code> mymkannotationview code> Vous devez vider l'image déjà définie code> dans la méthode code> PREPREPREPREPREUUSE CODE>.

var iconTypes = [AnnotationIcon]() // should be equal to the number of annotation

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    //...
    dequeuedAnnotationView.annotation = annotation
    dequeuedAnnotationView.iconType = iconType
}


4 commentaires

Bonjour @frankenstein, j'ai testé votre solution mais les images MkannotationView continuent d'être échangées entre elles. La mkannotation entière pourrait-elle être déplacée?


Avez-vous vérifié l'exactitude de votre logique? Où définissez-vous exactement icontype que vous passez pour obtenir l'image comme paramètre?


J'ai défini cette valeur lorsque l'utilisateur appuyez sur un bouton de l'utilisateur: Par exemple, si l'utilisateur appuyez sur un bouton pour indiquer que l'emplacement est le temps déterminé, l'ENUM VARIABE est défini sur .Trakeingicon. J'ai mis à jour le message avec des images décrivant le problème.


@Andonidasilva Comme soupçonnait que c'était parce que vous essayiez de définir l'image avant icontype a été définie. Vérifiez la mise à jour. J'espère que ça vous aidera.



0
votes

Votre problème est que vous définissez uniquement la propriété icontype code> lorsque vous créez la vue Annotation. Lorsqu'une vue d'annotation est réutilisée, vous définissez l'image en fonction de cette propriété plutôt que l'annotation actuelle.

Vraiment, il n'y a pas besoin de la propriété icontype code>. Vous devriez toujours utiliser une valeur code> icône code> de votre annotation. L'annotation est le modèle de données. P>

Vous ne définissez pas correctement la propriété Annotation de la vue CODE> dans le cas de la réutilisation. P>

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        
        guard let myAnnotation = annotation as? MyAnnotation else {
            return nil
        }
        
        let identifier = "Custom annotation"
           
        var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MyMKAnnotationView
        if annotationView == nil {
            annotationView = MyMKAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView?.canShowCallout = true
            annotationView?.translatesAutoresizingMaskIntoConstraints = false
            annotationView?.widthAnchor.constraint(equalToConstant: 35).isActive = true
            annotationView?.heightAnchor.constraint(equalToConstant: 35).isActive = true
        }
        annotationView?.annotation = MyAnnotation
        annotationView?.image = UIImage(named: MyAnnotation.icon.rawValue)
        
        return annotationView
    }


2 commentaires

Paul, le problème est qu'au moment de la réutilisation, si j'utilise directement la valeur stockée dans la variable de classe "Annotationicon", cette valeur peut ne pas correspondre au type d'annotation. Par exemple, lorsque je mettais une annotation de type destination, il s'agit de la valeur stockée dans la variable de classe "Annotationicon", par conséquent au moment de la réutilisation, toutes les annotations montreraient l'image de la valeur "Destination". C'est pourquoi je voulais attribuer à chaque mkannotation l'image qu'il doit montrer en utilisant une sous-classe.


Vous ne devriez pas utiliser une propriété de classe. Le type d'icône doit être une propriété de votre annotation. Les vues ne doivent pas stocker l'état; Ils sont légers et réutilisables. Votre modèle de données Stores State (dans ce cas, votre annotation est votre. Odel)



0
votes

J'ai résolu ce problème sous-classant la mkpoingannotation pour savoir quel type d'annotation que je répète: xxx pré>

par exemple, l'annotation de taxi est une sous-classe de mkpointsannotation: p>

map.register(MyOriginView.self, forAnnotationViewWithReuseIdentifier: annotationOriginID)
        map.register(MyDestinyView.self, forAnnotationViewWithReuseIdentifier: annotationDestinyID)
        map.register(MyTaxiView.self, forAnnotationViewWithReuseIdentifier: annotationTaxiID)


0 commentaires