addAnnotations方法仅将最后一个注释放在Array中

时间:2017-11-14 15:52:51

标签: ios swift mapkit

我在向mapView添加注释时遇到问题。我用这段代码取得了成功:

func placeAnnotations() {

    for _ in placeDetails {

        let multipleAnnotations = MKPointAnnotation()
        multipleAnnotations.title = place.address
        multipleAnnotations.subtitle = place.phone
        multipleAnnotations.coordinate = CLLocationCoordinate2D(latitude: place.lat, longitude: place.lng)
       mapView.addAnnotation(multipleAnnotations)

    }

}

问题是,它不符合我的Place类,因此没有显示自定义标题,字幕和MKAnnotationView。这是viewDidLoad()中的代码,我正在尝试放置所有注释,但它只是添加最后一个注释。我知道它覆盖了所有以前的数组,但没有找到任何其他方法/方法来实现。

  var placeDetails = [Place]()
    var places = [Place]()

        override func viewDidLoad() {
            super.viewDidLoad()

            downloadPlaceID {
                for obj in places {
                    place.downloadDetails(input: obj.placeId, completed: {
                        self.placeDetails.append(obj)
                     //self.placeAnnotations()
   self.mapView.addAnnotations(self.placeDetails)
                    })

                }
            }
        }

这是我的班级,所有数据都符合MKAnnotation 协议和函数,downloadPlaceID()和downloadDetails()

 class Place: NSObject, MKAnnotation {

        var coordinate: CLLocationCoordinate2D
        var placeId: String!
        var vicinity: String!
        var phone: String!
        var workHours: Bool!
        var lat: Double!
        var lng: Double!
        var address: String!

        var subtitle: String? {
            return phone
        }

        var title: String? {
            return address
        }



        var _placeId: String {
            if placeId == nil {
                placeId = ""
            }
            return placeId
        }

        var _vicinity: String {
            if vicinity == nil {
                vicinity = ""
            }
            return vicinity
        }

        var _phone: String {
            if phone == nil {
                phone = ""
            }
            return phone
        }

        var _workHours: Bool {
            if workHours == nil {
                workHours = false
            }
            return workHours
        }

        var _lat: Double {
            if lat == nil {
                lat = 0.0
            }
            return lat
        }

        var _lng: Double {
            if lng == nil {
                lng = 0.0
            }
            return lng
        }

        var _address: String {
            if address == nil {
                address = ""
            }
            return address
        }



        init(place: [String:Any]) {

            if let ids = place["place_id"] as? String {
                self.placeId = ids
            }

            if let vicinities = place["vicinity"] as? String {
                self.vicinity = vicinities
            }

            self.coordinate = CLLocationCoordinate2DMake(0.0, 0.0)

        }

        func downloadDetails(input: String, completed: @escaping DownloadComplete) {

            let details = "\(detailsBaseURL)\(detailsPlaceId)\(input)\(detailsKey)\(detailsSearchAPIKey)"

            Alamofire.request(details).responseJSON { response in
                let result = response.result


                if let dictionary = result.value as? [String:Any] {

                    if let result = dictionary["result"] as? [String:Any] {

                        if let phoneNumber = result["formatted_phone_number"] as? String {
                            self.phone = phoneNumber
                        }

                        if let  geometry = result["geometry"] as? [String:Any] {
                            if let location = geometry["location"] as? [String:Any] {
                                if let latitude = location["lat"] as? Double {
                                    self.lat = latitude
                                }
                                if let longitude = location["lng"] as? Double {
                                    self.lng = longitude
                                }

                                self.coordinate = CLLocationCoordinate2DMake(self.lat, self.lng)

                            }
                        }

                        if let openingHours = result["opening_hours"] as? [String:Any] {
                            if let openNow = openingHours["open_now"] as? Bool {
                                self.workHours = openNow
                            }
                        }

                        if let addressComponents = result["address_components"] as? [[String:Any]] {
                            let longName = addressComponents[1]["long_name"] as? String
                            let shortName = addressComponents[0]["long_name"] as? String

                            self.address = "\(longName!),\(shortName!)"
                        }
                    }
                }
                completed()
            }
        }
    }






 func downloadPlaceID (completed: @escaping DownloadComplete) {

        let placeURL = URL(string: nearbyURL)

        Alamofire.request(placeURL!).responseJSON { (response) in
            let result = response.result

            if let dictionary = result.value as? [String:Any] {
                if let results = dictionary["results"] as? [[String:Any]] {

                    if let status = dictionary["status"] as? String  {
                        if status == "OK" {
                            for obj in results {
                                place = Place(place: obj)
                                places.append(place)
                            }
                        } else {
                            print("jede govna")
                        }
                    }
                }
            }
            completed()
        }

1 个答案:

答案 0 :(得分:0)

这里有一些奇怪的变量名称和概念混合,这使得你的代码有点难以理解。

例如,将您调用的变量vicinities(复数)分配给名为vicinity的属性,为singular。或者不将downloadDetails功能与数据模型分开。

除此之外,通过在每个循环中将[MKAnnotation]数组添加到地图中,我认为您不必多次将MKAnnotations添加到地图中。

我怀疑你已经这样做了,因为你已经让自己很难知道整个数组何时更新了它的细节。

作为快速解决方法,我建议您更改downloadDetails功能,将completed功能调用到您刚刚下载详细信息的位置。这是你想要做的一个非常简化但有效的版本。首先是你的Place课程:

class Place: NSObject, MKAnnotation {
    var coordinate: CLLocationCoordinate2D

    override init() {
        coordinate = CLLocationCoordinate2DMake(0, 0)
    }

    func downloadDetails(completed: @escaping (Place) -> Void) {
        // Instead of downloading details we are just creating random positions
        self.coordinate = CLLocationCoordinate2DMake(CLLocationDegrees(arc4random_uniform(50)), CLLocationDegrees(arc4random_uniform(50)))

        // Return the object you've just built
        completed(self)
    }
}

现在在你的视图控制器中,我开始使用50个Place个对象的数组,获取它们的详细信息并将它们放在地图上:

var places = [Place]()
for _ in 1...50 {
    places.append(Place())
}

for place in places {
    place.downloadDetails(completed: { (placeWithDetails) in
        self.mapView.addAnnotation(placeWithDetails)
    })
}

这会导致地图填充50个随机位置:

iPhone Simulator showing 50 random annotation points on a mapview