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

Ios 从地图中删除注释并替换为更新的注释(qTree),ios,swift,mkmapview,mkannotation,Ios,Swift,Mkmapview,Mkannotation,我目前正在将群集注释添加到地图视图中。除了几件事外,一切正常。首先,当用户离开并返回视图时,我需要刷新地图上的注释。目前这类工作。。。问题是,不是删除注释并添加新注释,而是在旧注释的基础上添加新注释,因此每次都会成倍增加 下一个问题是,每个注释显示用户与该注释的距离,但是注释是在找到用户位置之前设置的。我假设,一旦找到位置,我将不得不删除并替换注释,但随后我又遇到了注释重复的问题 这是我的代码: override func viewDidAppear(animated: Bool) {

我目前正在将群集注释添加到地图视图中。除了几件事外,一切正常。首先,当用户离开并返回视图时,我需要刷新地图上的注释。目前这类工作。。。问题是,不是删除注释并添加新注释,而是在旧注释的基础上添加新注释,因此每次都会成倍增加


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

这是我的代码:

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中删除它们的方法。

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

我认为您可以尝试这样查找用户位置

let locationManager: CLLocationManager = CLLocationManager()
(将其作为类属性写入,而不是在任何viewDidLoad中!)

然后你马上就有了locationManager坐标

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

能否打印“annotationsToRemove as[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?奇怪的人,请尽可能多地在这些行上打印,并告诉我们它们是什么,以便我们可以帮助

我可以删除注释,但它们仍然存储在qTree中,我相信,因此当我添加新注释时,它们会与旧注释一起添加到qTree中。好的,什么是qTree?这些注释代表什么?您如何创建副本?是否在本地创建新批注?注释中是否保存了一些可用于识别重复项的密钥?请编辑您的原始问题,并提供有关您试图解决的问题的更多详细信息(而不是代码、描述性信息)。注释基本上包括骑乘设施的名称、骑乘设施的等待时间以及用户与该骑乘设施的距离。创建重复项是因为每次视图出现时我都调用
setUpMapView()
,并且每次都将骑乘设施的所有注释添加到qTree(和地图)中。当视图消失时,我需要一种方法从qTree(和地图,尽管我已经知道如何做)中删除旧注释。这与OPs问题有什么关系?下一个问题是每个注释显示用户与该注释的距离,但是,注释是在找到用户位置之前设置的。我假设在找到位置后,我只需删除并替换注释,但随后我又遇到了注释重复的问题。因此,我回答的第一部分是告诉OP如何在设置注释之前首先找到用户位置。annotationsToRemove as[AnyObject]//确定,这开始显示出连贯的答案。为什么不去编辑你的答案,以清楚你在说什么,而不是简洁到完全神秘的地步呢?只是想知道,你真的需要使用集群的游乐设施。我是说主题公园有多少游乐设施?我不是想批评你的项目,只是说可能有点过火了。如果您担心性能,您可以只加载当前可见视图中的注释。目前大约有40个注释,但我会在某个时候添加餐厅和其他设施,以便增加到100-150个注释。