2017-10-10 3 views
2

ich bin einen einfachen View-Controller mit einer Karte erstellen und 100-200 MKPointAnnotation die 11 MKMarkerAnnotationView iOS'NSInvalidArgumentException' bei der Verwendung von MapKit

Dies ist der viewDidLoad des Controllers

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.mapView.register(StationAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier) 
    self.mapView.register(StationClusterView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier) 

    locationDelegate.delegate = self 
    self.mapView.delegate = self 
    self.mapView.showsUserLocation = true 
    self.refreshData() 
    self.establishUserPosition() 
} 

Dann i laden sie die Sender aus einer JSON (Netzwerkobjekt) und ich hinzufügen, um sie alle zu dem mapview

func reloadViews(){ 
    if let network = network{ 
     for station in network.stations{ 
      let annotation = StationAnnotation(station: station) 
      annotations.append(annotation) // I add the annotations to an array to prevent them to be deallocated 
      mapView.addAnnotation(annotation) 
     } 
    } 
} 

Dies ist meine persönliche Anmerkung

class StationAnnotation : MKPointAnnotation{ 
var station : Station? 
var tintColor : UIColor?{ 
    if self.station?.free_bikes ?? 0 > 0 { 
     return .green 
    }else{ 
     return .red 
    } 
} 

var glyphImage : UIImage?{ 
    if self.station?.extra.status == "online"{ 
     return UIImage(named: "Bicycle") 
    }else{ 
     return UIImage(named: "Ban") 
    } 
} 

override init() { 
    super.init() 
} 

convenience init(station : Station){ 
    self.init() 
    self.title = station.name 
    self.coordinate = CLLocationCoordinate2D(latitude: station.latitude, longitude: station.longitude) 
    self.station = station 
    if station.extra.status == "online"{ 
     self.subtitle = "Bikes: \(station.free_bikes) - Slots: \(station.empty_slots)" 
    }else{ 
     self.subtitle = station.extra.status 
    } 
} 
} 

Und meine Gewohnheiten Ansichten

class StationAnnotationView : MKMarkerAnnotationView{ 

override var annotation: MKAnnotation? { 
    willSet { 
     if let annotation = newValue as? StationAnnotation{ 

      self.markerTintColor = annotation.tintColor 
      self.clusteringIdentifier = "station" 
      self.glyphImage = annotation.glyphImage 
     } 
    } 
} 
} 


class StationClusterView: MKAnnotationView { 

override init(annotation: MKAnnotation?, reuseIdentifier: String?) { 
    super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 
} 

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 onlineCount = cluster.memberAnnotations.filter { member -> Bool in 
       return (member as! StationAnnotation).station?.extra.status == "online" 
       }.count 
      image = renderer.image { _ in 
       // Fill full circle with tricycle color 
       UIColor(named: "Forbidden")?.setFill() 
       UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 40, height: 40)).fill() 

       // Fill pie with unicycle color 
       UIColor(named: "Available")?.setFill() 
       let piePath = UIBezierPath() 
       piePath.addArc(withCenter: CGPoint(x: 20, y: 20), radius: 20, 
           startAngle: 0, endAngle: (CGFloat.pi * 2.0 * CGFloat(onlineCount))/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: 20)] 
       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) 
      } 
     } 
    } 
} 

} 

Ich weiß nicht, warum die App während Kneifen, Zoomen oder Schwenken, Crash mit SIGABRT Signal und diese Ausnahme

*** Terminating app due to uncaught exception 
'NSInvalidArgumentException', reason: '*** -[__NSDictionaryM setObject:forKey:]: key cannot be nil' 

I‘ Ich habe versucht, jede Art von Debug-System und die Verwendung von Ausnahme Breakpoint hat nicht geholfen ... haben Sie irgendwelche Vorschläge?

+0

Das nil Betrieb Koaleszenz in Ihrem 'tintColor' nie> 0 zurück gehen Sie können es nicht so verwenden. Ich würde vorschlagen, die Option insgesamt zu löschen und seinen Standardwert auf 0 festzulegen. – brandonscript

+0

Wie bei Ihrem Fehler ist einer der Schlüssel für eines der Wörterbücher oder Attribute, die Sie festlegen, Null. Sie müssen bei jedem Schritt auf dem Weg einen Haltepunkt setzen und jeden Wert prüfen. Es könnte "Attribute" sein, es könnte 'text.size()' sein, oder irgendwo anders. – brandonscript

+0

"oder woanders ganz" so, kein Hinweis ahaha danke trotzdem :) –

Antwort

0

Hallo allerseits, ich finde Lösungen. Anfangs - es s..t passiert, wenn wir

mapView.register(AnyClass?, forAnnotationViewWithReuseIdentifier: String) 

und

mapView.dequeueReusableAnnotationView(withIdentifier: String) 

gibt nil zurück verwenden.

So heiß fix: Anzahl:

ViewController: UIViewController, MKMapViewDelegate 

hinzufügen

override func viewDidLoad() { 
     super.viewDidLoad() 
     mapView.delegate = self 

     mapView.register(MarkerPointView.self, forAnnotationViewWithReuseIdentifier: "marker") 
     mapView.register(ClusterView.self, forAnnotationViewWithReuseIdentifier: "cluster") 
} 

und finaly:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 

     if let marker = annotation as? MarkerAnnotation{ 
      var view = mapView.dequeueReusableAnnotationView(withIdentifier: "marker") as? MarkerPointView 
      if view == nil { 
//Very IMPORTANT 
       print("nil for Marker") 
       view = MarkerPointView(annotation: marker, reuseIdentifier: "marker") 
      } 
      return view 
     }else if let cluster = annotation as? MKClusterAnnotation{ 
      var view = mapView.dequeueReusableAnnotationView(withIdentifier: "cluster") as? ClusterView 
      if view == nil{ 
//Very IMPORTANT 
       print("nil for Cluster") 
       view = ClusterView(annotation: cluster, reuseIdentifier: "cluster") 
      } 
      return view 
     } 
     else{ 
      return nil 
     } 
    } 

hoffen, dass es Hilfe für jemanden, und auf der nächsten U Apfel fix it, weil wir es benutzen können, wie sie auf wwdc2017 auf 36:50 sagten - wir KÖNNEN es NICHT löschen !!!!! !!!

Original-Beitrag auf forums.developer.apple.com

Verwandte Themen