2015-07-27 12 views
6

Ich arbeite gerade daran, meiner Kartenansicht Cluster-Anmerkungen hinzuzufügen. Alles funktioniert gut mit Ausnahme von ein paar Dingen. Zuallererst muss ich die Anmerkungen auf der Karte aktualisieren, wenn der Benutzer die Ansicht verlässt und zur Ansicht zurückkehrt. Im Moment ist diese Art von Arbeiten ... Das Problem ist, dass, anstatt die Annotationen zu entfernen und die neuen hinzuzufügen, die neuen hinzugefügt werden, zusätzlich zu den alten, so dass jedes Mal multipliziert wird.Anmerkungen aus der Karte entfernen und durch aktualisierte Anmerkungen ersetzen (qTree)

Das nächste Problem ist, dass jede Annotation die Entfernung anzeigt, die der Benutzer von dieser Annotation entfernt hat. Die Annotationen werden jedoch eingerichtet, bevor der Standort des Benutzers gefunden wird. Ich nehme an, ich werde nur die Annotationen entfernen und ersetzen müssen, sobald der Ort gefunden ist, aber dann laufe ich auf das Problem der Annotationen erneut.

Dies ist mein Code:

override func viewDidAppear(animated: Bool) { 
    println(rideArray.count) 

    setUpMapView() 
} 

func setUpMapView() { 
    rideArray = ((DataManager.sharedInstance.rideArray) as NSArray) as! [Ride] 

    myLocation = mapView.userLocation.coordinate as CLLocationCoordinate2D 

    zoomRegion = MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2D(latitude: parkPassed.latitude!, longitude: parkPassed.longitude!), 1000, 1000) 
    mapView.setRegion(zoomRegion, animated: true) 
    mapView.delegate = self 

    for ride in rideArray { 
     println("Location: \(mapView.userLocation.coordinate.latitude)") 

     var subtitle = "" 
     if mapView.userLocation.location == nil { 
      subtitle = "Distance unavailable" 
     } else { 
      let userLocation = CLLocation(latitude: mapView.userLocation.coordinate.latitude, longitude: mapView.userLocation.coordinate.longitude) 
      let annotationLocation = CLLocation(latitude: ride.latitude!, longitude: ride.longitude!) 

      var distance = Int(CLLocationDistance(annotationLocation.distanceFromLocation(userLocation))) 

      if distance > 1000 { 
       distance = distance/1000 
       subtitle = "\(distance) kilometers" 
      } else { 
       subtitle = "\(distance) meters" 
      } 
     } 

     let annotation = RideAnnotation(coordinate: CLLocationCoordinate2DMake(ride.latitude!, ride.longitude!), title: ride.name!, subtitle: subtitle) 
     self.qTree.insertObject(annotation) 
    } 

    var leftSwipe = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:")) 
    var rightSwipe = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:")) 

    leftSwipe.direction = .Left 
    rightSwipe.direction = .Right 

    view.addGestureRecognizer(leftSwipe) 
    view.addGestureRecognizer(rightSwipe) 
} 

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! { 
    if annotation.isKindOfClass(QCluster.classForCoder()) { 
     let PinIdentifier = "PinIdentifier" 
     var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(ClusterAnnotationView.reuseId()) as? ClusterAnnotationView 

     if annotationView == nil { 
      annotationView = ClusterAnnotationView(cluster: annotation) 
     } 
     annotationView!.cluster = annotation 

     return annotationView 
    } else if annotation.isKindOfClass(RideAnnotation.classForCoder()) { 
     var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier("RideAnnotation") 

     if pinView == nil { 
      pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: "RideAnnotation") 
      pinView?.canShowCallout = true 
      pinView?.rightCalloutAccessoryView = UIButton.buttonWithType(UIButtonType.DetailDisclosure) as! UIButton 
      pinView?.rightCalloutAccessoryView.tintColor = UIColorFromRGB(0x424242) 

      let rideTimeView = UIView() 
      rideTimeView.frame = CGRectMake(5, 5, 50, 50) 
      rideTimeView.layer.cornerRadius = 25 

      let waitTimeLabel = UILabel() 
      waitTimeLabel.frame = CGRectMake(0, 0, 50, 50) 
      if DataManager.sharedInstance.getRideByName(annotation.title!)!.waitTime! == "Closed" { 
       waitTimeLabel.text = "\(DataManager.sharedInstance.getRideByName(annotation.title!)!.waitTime!)" 
       rideTimeView.backgroundColor = getColorFromNumber(80) 
       waitTimeLabel.font = UIFont(name: "Avenir", size: 15) 
      } else { 
       waitTimeLabel.text = "\(DataManager.sharedInstance.getRideByName(annotation.title!)!.waitTime!)m" 
       rideTimeView.backgroundColor = getColorFromNumber(DataManager.sharedInstance.getRideByName(annotation.title!)!.waitTime!.toInt()!) 
       waitTimeLabel.font = UIFont(name: "Avenir", size: 20) 
      } 
      waitTimeLabel.textAlignment = NSTextAlignment.Center 
      waitTimeLabel.textColor = UIColor.whiteColor() 
      waitTimeLabel.adjustsFontSizeToFitWidth = true 
      waitTimeLabel.numberOfLines = 1 

      rideTimeView.addSubview(waitTimeLabel) 

      pinView.leftCalloutAccessoryView = rideTimeView 
      pinView?.image = UIImage(named: "rideMapAnnotation") 
     } else { 
      pinView?.annotation = annotation 

      let rideTimeView = UIView() 
      rideTimeView.frame = CGRectMake(5, 5, 50, 50) 
      rideTimeView.layer.cornerRadius = 25 

      let waitTimeLabel = UILabel() 
      waitTimeLabel.frame = CGRectMake(0, 0, 50, 50) 
      if DataManager.sharedInstance.getRideByName(annotation.title!)!.waitTime! == "Closed" { 
       waitTimeLabel.text = "\(DataManager.sharedInstance.getRideByName(annotation.title!)!.waitTime!)" 
       rideTimeView.backgroundColor = getColorFromNumber(80) 
       waitTimeLabel.font = UIFont(name: "Avenir", size: 15) 
      } else { 
       waitTimeLabel.text = "\(DataManager.sharedInstance.getRideByName(annotation.title!)!.waitTime!)m" 
       rideTimeView.backgroundColor = getColorFromNumber(DataManager.sharedInstance.getRideByName(annotation.title!)!.waitTime!.toInt()!) 
       waitTimeLabel.font = UIFont(name: "Avenir", size: 20) 
      } 
      waitTimeLabel.textAlignment = NSTextAlignment.Center 
      waitTimeLabel.textColor = UIColor.whiteColor() 
      waitTimeLabel.adjustsFontSizeToFitWidth = true 
      waitTimeLabel.numberOfLines = 1 

      rideTimeView.addSubview(waitTimeLabel) 

      pinView.leftCalloutAccessoryView = rideTimeView 
     } 
     return pinView 
    } 
    return nil 
} 

func reloadAnnotations(){ 
    if self.isViewLoaded() == false { 
     return 
    } 

    self.cacheArray.removeAll(keepCapacity: false) 

    let mapRegion = self.mapView.region 
    let minNonClusteredSpan = min(mapRegion.span.latitudeDelta, mapRegion.span.longitudeDelta)/5 
    let objects = self.qTree.getObjectsInRegion(mapRegion, minNonClusteredSpan: minNonClusteredSpan) as NSArray 

    for object in objects { 
     if object.isKindOfClass(QCluster){ 
      let c = object as? QCluster 
      let neighbours = self.qTree.neighboursForLocation((c?.coordinate)!, limitCount: NSInteger((c?.objectsCount)!)) as NSArray 
      for neighbour in neighbours { 
       let tmp = self.rideArray.filter({ 
        return $0.name == (neighbour.title)!! 
       }) 

       if find(self.cacheArray, tmp[0]) == nil { 
        self.cacheArray.insert(tmp[0], atIndex: self.cacheArray.count) 
       } 
      } 
     } else { 
      let tmp = self.rideArray.filter({ 
       return $0.name == (object.title)!! 
      }) 

      if find(self.cacheArray, tmp[0]) == nil { 
       self.cacheArray.insert(tmp[0], atIndex: self.cacheArray.count) 
      } 
     } 
    } 

    let annotationsToRemove = (self.mapView.annotations as NSArray).mutableCopy() as! NSMutableArray 
    annotationsToRemove.removeObject(self.mapView.userLocation) 
    annotationsToRemove.removeObjectsInArray(objects as [AnyObject]) 
    self.mapView.removeAnnotations(annotationsToRemove as [AnyObject]) 
    let annotationsToAdd = objects.mutableCopy() as! NSMutableArray 
    annotationsToAdd.removeObjectsInArray(self.mapView.annotations) 

    self.mapView.addAnnotations(annotationsToAdd as [AnyObject]) 
} 

func mapView(mapView: MKMapView!, regionDidChangeAnimated animated: Bool) { 
    viewChanged = true 
    self.reloadAnnotations() 
} 

ich für die umfangreiche Menge an Code entschuldigen, aber es ist alles enthalten sein musste.

Jeder hat irgendwelche Vorschläge, wie ich die Anmerkungen entfernen und neu hinzufügen kann, sobald die Ansicht erscheint?

Danke!

EDIT:

Das zweite Problem ist nun behoben. Hier ist ein bisschen mehr Details in Bezug auf die Situation und das Problem:

Grundsätzlich jede Anmerkung stellt eine Fahrt in einem Themenpark und zeigt den Namen der Fahrt, aktuelle Wartezeit und Entfernung zu dieser Fahrt. In dem Moment, in dem ich setUpMapView() anrufe, wenn die Ansicht erscheint, werden alle Fahrtenkommentare jedes Mal zum qTree hinzugefügt, aber nicht entfernt. Dies ist das Problem, das ich zu lösen versuche, aber ich kann keine Möglichkeit finden, sie aus dem qTree zu entfernen.

+0

Nur wundernd, brauchen Sie wirklich Clustering für die Fahrten zu verwenden. Ich meine, wie viele Fahrten gibt es im Themenpark?Ich versuche nicht, dein Projekt anzugreifen, ich sage nur, dass es vielleicht etwas übertrieben ist. Wenn Sie sich Sorgen um die Leistung machen, können Sie einfach die Anmerkungen in der aktuellen sichtbaren Ansicht laden. –

+0

Momentan sind es ungefähr 40, aber ich werde irgendwann Restaurants und andere Einrichtungen hinzufügen, so dass sich diese auf 100-150 erhöhen können. – user3746428

Antwort

1

MKMapView verfügt über die Methode removeAnnotation:, die eine einzelne Annotation entfernt, und removeAnnotations:, die ein Array von Annotationen entfernt. Es hat auch eine annotations Eigenschaft, die Sie das aktuelle Array von Anmerkungen ermöglicht. Sie sollten in der Lage sein, die Anmerkungen auszuwählen und zu entfernen, die Sie entfernen möchten, und dann neue hinzuzufügen, um sie zu ersetzen.

+0

Ich kann die Annotationen entfernen, aber sie sind immer noch in der qTree gespeichert, ich glaube, wenn ich also die neuen hinzufüge, werden sie in die qTree mit den alten hinzugefügt. – user3746428

+0

Ok, was ist ein qTree? Was bedeuten diese Anmerkungen und wie erstellen Sie Duplikate? Erstellen Sie neue Anmerkungen lokal? Ist in den Anmerkungen ein Schlüssel gespeichert, mit dem Duplikate erkannt werden können? Bitte bearbeiten Sie Ihre ursprüngliche Frage mit viel mehr Details (nicht Code, beschreibende Informationen) über das Problem, das Sie versuchen zu lösen. –

+0

Die Anmerkungen haben grundsätzlich den Namen einer Fahrt, die Wartezeit für diese Fahrt und die Entfernung, die der Benutzer von dieser Fahrt hat. Die Duplikate werden erstellt, weil ich 'setUpMapView()' jedesmal aufrufen werde, wenn die Ansicht erscheint, und alle Anmerkungen von der Fahrt werden jedes Mal dem qTree (und der Karte) hinzugefügt. Ich brauche eine Möglichkeit, die alten Annotationen aus dem qTree zu entfernen (und map, obwohl ich weiß, wie man dieses Bit schon macht), wenn die Ansicht verschwindet. – user3746428

-1

ich glaube, Sie könnten versuchen, Benutzer Ort wie diese

let locationManager: CLLocationManager = CLLocationManager() 

(schreiben diese als Klasseneigenschaft, nicht in jedem viewDidLoad!) Zu finden

dann u sofort haben Locationmanager koordiniert.

self.mapView.removeAnnotations(annotationsToRemove as [AnyObject]) 

könnten Sie die „annotationsToRemove als [ANYOBJECT]“ drucken und uns sagen, was der Inhalt ist? tatsächlich all dieser Code ist verdächtig:

let annotationsToRemove = (self.mapView.annotations as NSArray).mutableCopy() as! NSMutableArray 
annotationsToRemove.removeObject(self.mapView.userLocation) 
annotationsToRemove.removeObjectsInArray(objects as [AnyObject]) 
self.mapView.removeAnnotations(annotationsToRemove as [AnyObject]) 

definieren Sie eine Konstante, bearbeiten es dann mit removeObjects und es dann zu RemoveAnnotations passieren? merkwürdiger Mann, bitte so viele Drucke auf diesen Zeilen wie Sie können und sagen, was sie sind, damit wir helfen können

+1

Was hat das mit der OP-Frage zu tun? –

+0

wow Herr, Sie müssen die Frage vor dem Abstimmen lesen. – Ammo

+0

Das nächste Problem ist, dass jede Annotation die Entfernung anzeigt, die der Benutzer von dieser Annotation entfernt hat. Die Annotationen werden jedoch eingerichtet, bevor der Standort des Benutzers gefunden wird. Ich nehme an, ich werde nur die Annotationen entfernen und ersetzen müssen, sobald der Ort gefunden ist, aber dann laufe ich auf das Problem der Annotationen erneut. – Ammo