从地图中删除注释并替换为更新的注释(qTree)

时间:2015-07-27 19:50:59

标签: ios swift mkmapview mkannotation

我目前正致力于将集群注释添加到地图视图中。除了几件事之外,一切都很好。首先,我需要在用户离开并返回视图时刷新地图上的注释。目前这种工作......问题在于,除了删除注释和添加新注释之外,新增的注释只是添加了旧注释,因此每次都会增加。

下一个问题是每个注释显示用户与该注释的距离,但注释是在找到用户位置之前设置的。我假设一旦找到位置,我将只需删除并替换注释,但后来又遇到了重复注释的问题。

这是我的代码:

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()
}

我为大量的代码道歉,但这一切都必须包括在内。

任何人都有关于如何删除注释并在视图出现后重新添加注释的任何建议?

谢谢!

修改

第二个问题现已解决。以下是有关情况和问题的更多细节:

基本上每个注释代表一个主题公园的骑行并显示骑行名称,当前等待时间和到该骑行的距离。当我在视图出现时调用setUpMapView()时,所有的骑行注释每次都被添加到qTree,但是没有被删除。这是我要解决的问题,但我无法找到从qTree中删除它们的方法。

2 个答案:

答案 0 :(得分:2)

MKMapView的方法removeAnnotation:将删除一个注释,而removeAnnotations:将删除一个注释数组。它还具有annotations属性,可以使用当前的注释数组。您应该能够选择并删除要删除的注释,然后添加新注释以替换它们。

答案 1 :(得分:-1)

我认为你可以尝试找到像这样的用户位置

let locationManager: CLLocationManager = CLLocationManager()

(将其写为类属性,而不是在任何viewDidLoad中!)

然后你立即拥有locationManager坐标。

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

你可以将" annotationsToRemove打印为[AnyObject]"并告诉我们内容是什么? 实际上所有这些代码都是可疑的:

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

你定义一个常量,然后用removeObjects编辑它,然后将它传递给removeAnnotations?奇怪的是,请尽可能多地在这些线上打印并告诉他们是什么,以便我们可以提供帮助