【发布时间】:2021-10-02 06:08:32
【问题描述】:
我正在尝试使用 getVenues() 函数显示从网络调用中获取的场所的注释。我在地图视图上看不到任何东西。
import UIKit
import MapKit
class VenueMapViewController: UIViewController {
// MARK: - Outlets
@IBOutlet weak var mapView: MKMapView!
// MARK: - Properties
var annotations = [MKAnnotation]()
var venues = [Venue]()
var place: SavedPlace?
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupMapView()
getVenues()
setupAnnotations(for: venues)
}
// MARK: - Helpers
fileprivate func setupMapView() {
self.mapView.delegate = self
self.mapView.layer.cornerRadius = 20
}
fileprivate func setupAnnotations(for venues: [Venue]) {
for venue in venues {
let annotation = VenueAnnotation(
title: venue.name,
locationName: venue.categories.map({$0.shortName}).first,
coordinate: CLLocationCoordinate2D(latitude: venue.location.lat, longitude: venue.location.lng))
self.annotations.append(annotation)
}
self.mapView.addAnnotations(annotations)
self.mapView.showAnnotations(annotations, animated: true)
}
下面,我从 Foursquare API 获取场地,然后将响应结果分配给场地数组。位置名称来自前一个视图控制器的选定城市。
fileprivate func getVenues() {
if let place = place {
if let locationName = place.locationName {
NetworkService.getRestaurants(with: locationName) { result in
DispatchQueue.main.async {
switch result {
case .success(let venues):
let venues = venues.map({$0.venue})
self.venues = venues
case .failure(let error):
print("Error in \(#function) : \(error.localizedDescription) \n---\n \(error)")
}
}
}
}
}
}
}
为 MKAnnotation 创建一个视图
extension VenueMapViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let annotation = annotation as? VenueAnnotation {
let identifier = "pin"
var view: MKPinAnnotationView
if let dequeuedView = self.mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView {
dequeuedView.annotation = annotation
view = dequeuedView
} else {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.calloutOffset = CGPoint(x: -5, y: 5)
view.rightCalloutAccessoryView = UIButton(type: .detailDisclosure) as UIView
}
return view
}
return nil
}
}
这是 MKAnnotation 的类
class VenueAnnotation: NSObject, MKAnnotation {
let title: String?
let locationName: String?
let coordinate: CLLocationCoordinate2D
init(title: String?, locationName: String?, coordinate: CLLocationCoordinate2D) {
self.title = title
self.locationName = locationName
self.coordinate = coordinate
super.init()
}
var subtitle: String? {
return locationName
}
}
SavedPlace 模型来自之前的视图控制器,如下所示。
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: Constants.Storyboards.venuesList, bundle: nil)
guard let venuesMapVC = storyboard.instantiateViewController(withIdentifier: Constants.ViewControllers.venuesMapVC) as? VenueMapViewController else { return }
guard let place = savedPlaces[indexPath.row] else { return }
venuesMapVC.place = place
self.navigationController?.pushViewController(venuesMapVC, animated: true)
}
Foursquare API 对场地的响应如下
meta = {
code = 200;
requestId = 61580e90a13f913edc44f6f9;
};
response = {
geocode = {
cc = GB;
center = {
lat = "51.50853";
lng = "-0.12574";
};
displayString = "London, Greater London, United Kingdom";
geometry = {
bounds = {
ne = {
lat = "51.69164399965589";
lng = "0.3341899970520341";
};
sw = {
lat = "51.28467404417054";
lng = "-0.5085579279369435";
};
};
};
longId = 72057594040571679;
slug = london;
what = "";
where = london;
};
groups = (
{
items = (
{
reasons = {
count = 0;
items = (
{
reasonName = globalInteractionReason;
summary = "This spot is popular";
type = general;
}
);
};
referralId = "e-0-4ac518d5f964a520e5a720e3-0";
venue = {
categories = (
{
icon = {
prefix = "https://ss3.4sqi.net/img/categories_v2/food/vegetarian_";
suffix = ".png";
};
id = 4bf58dd8d48988d1d3941735;
name = "Vegetarian / Vegan Restaurant";
pluralName = "Vegetarian / Vegan Restaurants";
primary = 1;
shortName = "Vegetarian / Vegan";
}
);
id = 4ac518d5f964a520e5a720e3;
location = {
address = "45 Lexington St";
cc = GB;
city = Soho;
country = "United Kingdom";
formattedAddress = (
"45 Lexington St",
Soho,
"Greater London",
"W1F 9AN",
"United Kingdom"
);
labeledLatLngs = (
{
label = display;
lat = "51.51303400019872";
lng = "-0.1363922461877476";
}
);
lat = "51.51303400019872";
lng = "-0.1363922461877476";
neighborhood = "Soho, London, Greater London";
postalCode = "W1F 9AN";
state = "Greater London";
};
name = Mildreds;
photos = {
count = 0;
groups = (
);
};
};
},
{
reasons = {
count = 0;
items = (
{
reasonName = globalInteractionReason;
summary = "This spot is popular";
type = general;
}
);
};
【问题讨论】:
-
一个叫“场地”的人在哪里? Donde esta '场地'?
-
下面是干什么用的? var annotations = [MKAnnotation]() 不应该是 var annotations = [VenueAnnotation]() 吗?
-
嗨@ElTomato,Place 来自以前的VC。我在最后添加了导航代码。我也尝试将 var 注释设为 [VenueAnnotation]()。场地来自 Foursquare API。
-
看起来是因为网络调用是同步的。您拨打
getVenues会启动网络呼叫,但不会立即结束。所以你然后打电话给setupAnnotations,但网络请求还没有完成,所以还没有场地。然后,当网络请求完成时,不会调用任何内容来为现在存在的场所设置注释。 -
我在
setupAnnotations()中用很少的硬编码VenueAnnotations 尝试了您的代码,它工作正常。所以请在致电setupAnnotations()时检查您是否有可用的场地@
标签: ios swift annotations mapkit mkannotation