#swift #uikit #mapkit
Вопрос:
Я французский новичок в Swift и хочу создать карту с аннотациями из файла JSON с помощью UIKit и MapKit. Я использую UIKit, потому что я хотел бы использовать много аннотаций, и я хочу, чтобы аннотации сворачивались в аннотацию кластера, если пользователь уменьшит масштаб.
Итак, проект построен, но ни одна из моих аннотаций не отображается
Большое спасибо всем, кто исправил мой код. Если у вас есть вопросы, не стесняйтесь задавать их мне. Заранее благодарю вас.
Итак, вот мой ViewController :
»’
import CoreLocation import UIKit import MapKit class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate { var locations = [Location]() @IBOutlet weak var mapView: MKMapView! let manager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() mapView.delegate = self mapView.register(LocationDataMapClusterView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier) } func AnnotationView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -gt; MKAnnotationView? { switch annotation { case is MKClusterAnnotation: return mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier, for: annotation) default: return nil } } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) manager.desiredAccuracy = kCLLocationAccuracyBest manager.delegate = self manager.requestWhenInUseAuthorization() manager.startUpdatingLocation() mapView.showsUserLocation = true readFile() mapView.addAnnotations(locations) } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let location = locations.first { manager.stopUpdatingLocation() render(location) } } func render(_ location:CLLocation){ let coordinate = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude) let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1) let region = MKCoordinateRegion(center: coordinate, span: span) mapView.setRegion(region, animated: true) } public func readFile() { if let url = Bundle.main.url(forResource : "capital", withExtension: "json"), let data = try? Data(contentsOf: url) { let decoder = JSONDecoder() if let jsonData = try? decoder.decode(JsonData.self, from: data){ self.locations = jsonData.locations print(locations) } } } }
»’
Мой файл JSON :
»’
{ "locations": [ { "id": 0, "name": "New York City", "latitude": 40.71, "longitude": -74 }, { "id": 1, "name": "Barcelona", "latitude": 41.38, "longitude": 2.17 }, { "id": 2, "name": "Tokyo", "latitude": 35.68, "longitude": 139.76 }, { "id": 3, "name": "Atlanta", "latitude": 33.74, "longitude": -84.38 }, { "id": 4, "name": "Paris", "latitude": 48.85, "longitude": 2.35 }, { "id": 5, "name": "Hong Kong", "latitude": 22.31, "longitude": 114.16 } ] }
»’
and my location class :
»’
import MapKit import UIKit class Location: NSObject, Decodable, Identifiable, MKAnnotation { var id: Int var name: String var latitude: Double var longitude : Double var coordinate: CLLocationCoordinate2D { .init(latitude: latitude, longitude: longitude) } init(id : Int, name : String, latitude : Double, longitude : Double){ self.id = id self.name = name self.longitude = longitude self.latitude = latitude } } struct JsonData : Decodable { let locations : [Location] }
»’
Ответ №1:
После некоторых исследований я обнаружил свою проблему :
- : MapView.addAnnotations должен использовать jsonData.locations, а не местоположения
»’
mapView.addAnnotations(jsonData.locations)
»’
- MapView.addAnnotations должны быть включены в функцию readfile следующим образом :
»’
public func readFile() { if let url = Bundle.main.url(forResource : "capital", withExtension: "json"), let data = try? Data(contentsOf: url) { let decoder = JSONDecoder() if let jsonData = try? decoder.decode(JsonData.self, from: data){ self.locations = jsonData.locations mapView.addAnnotations(jsonData.locations) } } }
»’
- и в конце мне просто нужно вызвать свою функцию в viewDidAppear :
»’
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) manager.desiredAccuracy = kCLLocationAccuracyBest manager.delegate = self manager.requestWhenInUseAuthorization() manager.startUpdatingLocation() mapView.showsUserLocation = true readFile() }
»’