Remove annotations from the map and replace them with updated annotations (qTree)

I am currently working on adding cluster annotations to my map view. Everything works fine except for a few things. First of all, I need to update the annotations on the map when the user leaves and returns to the view. At the moment, such works ... The problem is that instead of removing annotations and adding new ones, new ones are added in addition to the old ones, so they are multiplied every time.

The next problem is that each annotation shows the distance the user is from this annotation, however the annotations are configured before the user's location is found. I assume that I just need to remove and replace annotations after locating the location, but then again I ran into the problem of duplicate comments.

This is my 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() } 

I apologize for the large amount of code, but all this should have been included.

Does anyone have any suggestions on how I can remove annotations and re-add them after the view appears?

Thanks!

EDIT:

The second problem is now resolved. The following is more detailed information about the situation and problems:

Basically, each annotation is a trip to a theme park and displays the name of the trip, the current waiting time, and the distance to this trip. Currently, when I find setUpMapView() when the view appears, all ride annotations are added to qTree every time, but not deleted. This is a problem that I am trying to solve, but I cannot find a way to remove them from qTree.

+6
source share
2 answers

MKMapView has a removeAnnotation: method that will remove one annotation and removeAnnotations: which will remove the annotation array. It also has an annotations property that allows you to use the current annotation array. You should be able to select and delete annotations that you want to remove, and then add new ones to replace them.

+1
source

I think you could try finding a user’s location like this

 let locationManager: CLLocationManager = CLLocationManager() 

(write this as a class property, not inside any kind of DidLoad!)

then u instantly have locationManager coordinates.

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

Can you print "annotationsToRemove as [AnyObject]" and tell us what the content is? in fact, all this code is suspicious:

 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]) 

do you define a constant and then edit it with removeObjects and then pass it to remove annotations? strange person, please get as many prints on these lines as possible, and tell us what they are, so that we can help.

-1
source

All Articles