2017-11-12 3 views
2

Ich habe eine Kartenansicht mit zwei Arten von benutzerdefinierten Anmerkungsansichten. Ich frage mich, wie man verschiedene Arten von Clustern für diese Ansichten hinzufügen kann (abhängig von den Arten der Anmerkungsansichten). Derzeit habe ich versucht, alles wie im Beispielprojekt von WWDC 2017 Sitzung 237 "Was ist neu in MapKit". Aber wenn ich meine Clusteransicht registriere, tut sie nichts (sogar nicht aufgerufen). Ich nehme an, dass ich benutzerdefinierte Anmerkungsansichten verwende und sie nicht registriere, sondern stattdessen MKMapViewDelegate Methode mapView(_:viewFor:). Hier ist der Code, wo ich meine benutzerdefinierten Cluster Annotation registrieren (ClusterView eine Unterklasse von MKAnnotationView ist, wo ich meine Cluster Anmerkung definieren):Hinzufügen von Cluster-Anmerkungen zu einer Kartenansicht mit mehreren benutzerdefinierten Anmerkungsansichten

mapView.register(ClusterView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier) 

Der Code oben definiert ist in einer viewDidLoad() Methode, aber wieder, es funktioniert nicht sogar angerufen werden. Also, ich denke, ich sollte eine von MKMapViewDelegate Methoden implementieren: mapView(_:clusterAnnotationForMemeberAnnotations:). Das Problem ist, dass ich keine Erfahrung mit dem Hinzufügen von Cluster-Annotationen habe, daher weiß ich nicht, wie ich es richtig umsetzen soll. Ich habe seit einigen Wochen nach einigen Beispielen im Internet gesucht, aber noch nichts gefunden (nur über Bibliotheken von Drittanbietern). Wenn Sie wissen, wie Sie die oben genannte Methode oder eine andere Art des Hinzufügens von Clustern zu einer mapView Anwendung implementieren, die verschiedene Arten von benutzerdefinierten Anmerkungsansichten aufweist (ohne die Verwendung von Bibliotheken von Drittanbietern), wäre ich Ihnen dankbar.

Antwort

1

Versuchen Sie, Ihre Anmerkungen mit String Wiederverwendung Identifier registrieren:

mapView.register(AnnotationViewMarker.self, forAnnotationViewWithReuseIdentifier: "marker") 
mapView.register(AppleClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: "cluster") 

ich schon zu, dieses Problem hatte. Falls hier ein Beispiel, das in meiner app arbeiten:

override func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {   
    if annotation is MKUserLocation || annotation is UserAnnotation { 
     return nil 
    } 

    if let marker = annotation as? WifiAnnotation { 
     var view = mapView.dequeueReusableAnnotationView(withIdentifier: "marker") as? AnnotationViewMarker 
     if view == nil { 
      view = AnnotationViewMarker(annotation: marker, reuseIdentifier: "marker") 
     } 
     return view 

    } else if let cluster = annotation as? MKClusterAnnotation { 
     var view = mapView.dequeueReusableAnnotationView(withIdentifier: "cluster") as? AppleClusterAnnotationView 
     if view == nil { 
      view = AppleClusterAnnotationView(annotation: cluster, reuseIdentifier: "cluster") 
     } 
     return view 

    } 

    return nil 
} 

hier ein exemple meiner MKAnnotationView Klasse:

class AppleClusterAnnotationView: MKAnnotationView { 
override init(annotation: MKAnnotation?, reuseIdentifier: String?) { 
    super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 
    displayPriority = .defaultLow 
    //collisionMode = .circle 
    centerOffset = CGPoint(x: 0, y: -10) // Offset center point to animate better with marker annotations 
} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 

override var annotation: MKAnnotation? { 
    willSet { 
     if let cluster = newValue as? MKClusterAnnotation { 
      let renderer = UIGraphicsImageRenderer(size: CGSize(width: 40, height: 40)) 
      let count = cluster.memberAnnotations.count 
      let uniCount = cluster.memberAnnotations.filter { member -> Bool in 
       return (member as! WifiAnnotation).wifiType != "Ad" 
       }.count 
      image = renderer.image { _ in 
       // Fill full circle with tricycle color 
       UIColor(red: 52/255, green: 131/255, blue: 223/255, alpha: 0.22).setFill() 
       UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 40, height: 40)).fill() 

       // Fill pie with unicycle color 
       UIColor(red: 52/255, green: 131/255, blue: 223/255, alpha: 0.22).setFill() 
       let piePath = UIBezierPath() 
       piePath.addArc(withCenter: CGPoint(x: 20, y: 20), radius: 20, 
           startAngle: 0, endAngle: (CGFloat.pi * 2.0 * CGFloat(uniCount))/CGFloat(count), 
           clockwise: true) 
       piePath.addLine(to: CGPoint(x: 20, y: 20)) 
       piePath.close() 
       piePath.fill() 

       // Fill inner circle with white color 
       UIColor.white.setFill() 
       UIBezierPath(ovalIn: CGRect(x: 8, y: 8, width: 24, height: 24)).fill() 

       // Finally draw count text vertically and horizontally centered 
       let attributes = [ NSAttributedStringKey.foregroundColor: UIColor.black, 
            NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 15)] 
       let text = "\(count)" 
       let size = text.size(withAttributes: attributes) 
       let rect = CGRect(x: 20 - size.width/2, y: 20 - size.height/2, width: size.width, height: size.height) 
       text.draw(in: rect, withAttributes: attributes) 

      } 
     } 
    } 
}} 

Und schließlich meine MKMarkerAnnotationView. Damit sind Sie alle eingerichtet, damit es funktioniert. Sie müssen nur Ihre MKAnnotation einrichten.

MKMarkerAnnotationView:

class AnnotationViewMarker: MKMarkerAnnotationView { 

override open var annotation: MKAnnotation? { 
    willSet { 
     if let annotation = newValue as? WifiAnnotation { 
      clusteringIdentifier = "WifiAnnotation" 

      if annotation.wifiType == "yyy" { 
       glyphImage = UIImage(named: "yyy") 
       selectedGlyphImage = UIImage(named: "yyy") 
       markerTintColor = UIColor("#303030") 
       glyphTintColor = .white 
       displayPriority = .defaultHigh 
       titleVisibility = .visible 
       animatesWhenAdded = true 


      } else { 
       glyphImage = UIImage(named: "xxx") 
       selectedGlyphImage = UIImage(named: "xxx") 
       markerTintColor = UIColor("#3483DF") 
       glyphTintColor = .white 
       displayPriority = .required 
       titleVisibility = .visible 
       animatesWhenAdded = true 

       let accessButton = UIButton(frame: CGRect(x: 0, y: 0, width: 20, height: 20)) 
       accessButton.setImage(self.accessAnnotation, for: .normal) //UIImage(named: "accessAnnotation"), for: .normal) 
       rightCalloutAccessoryView = accessButton 
      } 

      //collisionMode = .circle 
     } 

    } 
} 

}

+0

Vielen Dank, es funktioniert. Meine Lösung sieht ähnlich aus. Ich habe es hier https://forums.developer.apple.com/thread/89427 gefunden –

Verwandte Themen