未出现在 MapKit 上的注释

annotations not appearing on MapKit

有没有人经历过在您的应用程序中打开地图,虽然它显示了您所在的区域,但没有显示蓝点。我还使用 localSearch 在我的应用程序中查找超市。当您最初打开地图时,它什么也没有显示。当您关闭并再次打开应用程序时,注释会神奇地出现。我错过了一些很明显的东西吗?

我也在控制台中收到这些错误:

环绕多边形而未完成...:-(

List has 10 nodes:
    7 8 9 10 4 3 0 1 2 6 
2022-02-20 17:55:28.093927+0900 GoferList[15460:5478085] [VKDefault] Building failed to triangulate!
2022-02-20 17:55:28.265877+0900 GoferList[15460:5478094] [Font] Failed to parse font key token: hiraginosans-w6

这是我正在使用的视图控制器:

import CoreLocation
import MapKit
import UIKit

class MapViewController: UIViewController {
    static func createViewController() -> MapViewController? {
        UIStoryboard(name: "Main", bundle: Bundle.main)
            .instantiateInitialViewController() as? MapViewController
    }

    @IBOutlet private var mapView: MKMapView!
    private let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()
        configureLocationManager()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        locationManager.startUpdatingLocation()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        locationManager.stopUpdatingLocation()
    }
}

// MARK: - Location Manager

extension MapViewController: CLLocationManagerDelegate {
    func configureLocationManager() {
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.distanceFilter = kCLDistanceFilterNone
    }

    func locationManager(
        _ mgr: CLLocationManager,
        didUpdateLocations locations: [CLLocation]
    ) {
        guard let location = locations.first else {
            return
        }
        let region = MKCoordinateRegion(
            center: location.coordinate,
            latitudinalMeters: 1000,
            longitudinalMeters: 1000
        )
        mapView.setRegion(region, animated: false)
        findPOIPlaces(query: "supermarket", region: region)
        mgr.stopUpdatingLocation()
    }
}

// MARK: - MapViewDelegate

extension MapViewController: MKMapViewDelegate {
    func findPOIPlaces(query: String, region: MKCoordinateRegion) {
        let searchRequest = MKLocalSearch.Request()
        searchRequest.naturalLanguageQuery = query
        searchRequest.resultTypes = .pointOfInterest
        searchRequest.region = region

        let search = MKLocalSearch(request: searchRequest)
        search.start { [weak self] res, error in
            guard let res = res,
                  let self = self,
                  error == nil
            else {
                print("\(String(describing: error))")
                return
            }
            for item in res.mapItems {
                let annotation = SuperMarketAnnotation(item: item)
                self.mapView.addAnnotation(annotation)
            }
        }
    }

    func mapView(
        _ mapView: MKMapView,
        viewFor annotation: MKAnnotation
    ) -> MKAnnotationView? {
        guard annotation is SuperMarketAnnotation else {
            return nil
        }
        if let view = mapView.dequeueReusableAnnotationView(
            withIdentifier: SuperMarketAnnotationView.reuseID)
        {
            return view
        }
        let annotationView = SuperMarketAnnotationView(annotation: annotation)
        annotationView.delegate = self
        return annotationView
    }
}

// MARK: - SuperMarketAnnotationViewDelegate

extension MapViewController: SuperMarketAnnotationViewDelegate {
    func onTapPin(annotation: SuperMarketAnnotation) {
        mapView.setCenter(annotation.coordinate, animated: true)
    }

    func onTapInfo(annotation: SuperMarketAnnotation) {
        if let url = annotation.webURL {
            // if place has an web site
            if let vc = WebViewController.createViewController() {
                vc.url = url
                vc.name = annotation.title
                present(vc, animated: true, completion: nil)
            }
        } else if let url = annotation.externalURL {
            UIApplication.shared.open(
                url, options: [:],
                completionHandler: nil
            )
        }
    }
}

有人可以帮忙吗?谢谢。

几点观察:

  • 关于看不到蓝点,问题是您是否设置了 showsUserLocation(以编程方式或在 NIB/storyboard 中)。

  • 关于注解不显示,您需要缩小问题范围。我会暂时删除 mapView(_:viewFor:) 并查看此时您是否看到注释。

    • 如果是,那么问题出在 mapView(_:viewFor:)(见下文)或您的自定义注释视图 subclass.
    • 如果它们没有出现,那么问题要么出在您添加注释的 how/when 逻辑中,要么出在您的自定义注释 class.
    • 删除 mapView(_:viewFor:) 后,您可以尝试添加 MKPointAnnotation,而不是 SuperMarketAnnotation。这将帮助您弄清楚问题是出在您的注释中 class 还是您添加注释的时间和位置的逻辑。
  • FWIW,mapView(_:viewFor:) 有一个小错误(可能相关也可能不相关)。如果您成功地使现有注释视图出列,您只是 return 它而永远不会更新它的 annotation 属性。您必须更新任何出列注释视图的 annotation,否则它将指向旧注释(特别是它的旧坐标)。

    if let view = mapView.dequeueReusableAnnotationView(withIdentifier: SuperMarketAnnotationView.reuseID) {
        view.annotation = annotation // make sure you update the annotation for dequeued annotation view
        return view
    }