【问题标题】:How can I show multiple annotations in a map view? #iOS如何在地图视图中显示多个注释? #iOS
【发布时间】: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


【解决方案1】:

添加这个

setupAnnotations(for: venues)

在 func getVenues() 成功块中。

在 viewDidLoad 场地数组是空的,所以什么都没有显示。

【讨论】:

  • 是的,我也在成功块中尝试过。还是不行
  • 检查场地阵列数..
  • 问题与网络有关...我不得不重新生成一个新的 API 密钥。感谢您的帮助
猜你喜欢
  • 2016-02-09
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多