未出现在 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
}
有没有人经历过在您的应用程序中打开地图,虽然它显示了您所在的区域,但没有显示蓝点。我还使用 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 }