MKMarkerAnnotationView 错误,由于未捕获的异常而终止应用程序
MKMarkerAnnotationView Error, Terminating app due to uncaught exception
enter image description here
在地图上显示标注时,可以构建并执行,但是执行过程中出错,停止了。
MKMarkerAnnotationView 显示聚类和字形图像。
大约有100个注解,在加载View的时候从Firestore获取并存储在一个数组中。
放大或移动地图时发生错误。
Swift 版本:Swift5
我也检查了插座连接,但看起来没有问题。
找不到解决办法,你能告诉我哪里出了问题吗?
写了Map等的设置方法,如果从根本上说错了,还望指教
错误
[XXX.CustomPinAnnotation memberAnnotations]:无法识别的选择器发送到实例 0x2835e16c0
- 由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'-[XXX.CustomPinAnnotation memberAnnotations]:无法识别的选择器发送到实例 0x2835e16c0' * 首先抛出调用堆栈:
CustomPinAnnotation.swift
import UIKit
import MapKit
class CustomPinAnnotation: NSObject, MKAnnotation {
let clusteringIdentifier : String
let title: String?
let subtitle: String?
let coordinate: CLLocationCoordinate2D
//let glyphText: String
let glyphImage: UIImage
let glyphTintColor: UIColor
let markerTintColor: UIColor
let objectid: Int
init(_ clusteringIdentifier: String, title: String, subtitle: String, coordinate: CLLocationCoordinate2D, glyphImage: UIImage, glyphTintColor: UIColor, markerTintColor: UIColor, objectid: Int) {
self.clusteringIdentifier = clusteringIdentifier
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
// self.glyphText = glyphText
self.glyphImage = glyphImage
self.glyphTintColor = glyphTintColor
self.markerTintColor = markerTintColor
self.objectid = objectid
}
}
ViewController.swift
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
var locationManager = CLLocationManager()
var userCoordinate = CLLocationCoordinate2D()
//object array
var objectAll = [objectData]()
//Map view
@IBOutlet weak var mapView: MKMapView!
func displayAllMountains() {
for mountain in objectAll {
let pinImage = UIImage.init(named: "XXXXX")!
let subtitletext = String(object.height) + "m"
let annotation = CustomPinAnnotation("clusterid", title:object.name, subtitle: subtitletext, coordinate: object.geopoint, glyphImage: pinImage, glyphTintColor: .white, markerTintColor: .darkGray, objectid: object.objectid)
self.mapView.addAnnotation(annotation)
}
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation === mapView.userLocation {
return nil
} else {
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation)
guard let markerAnnotationView = annotationView as? MKMarkerAnnotationView,
let annotation = annotation as? CustomPinAnnotation else {
return annotationView
}
markerAnnotationView.clusteringIdentifier = annotation.clusteringIdentifier
// markerAnnotationView.glyphText = annotation.glyphText
markerAnnotationView.glyphImage = annotation.glyphImage
markerAnnotationView.glyphTintColor = annotation.glyphTintColor
markerAnnotationView.markerTintColor = annotation.markerTintColor
return markerAnnotationView
}
}
}
你说它在报告:
Error [XXX.CustomPinAnnotation memberAnnotations]: unrecognized selector sent to instance 0x2835e16c0
memberAnnotations
是一种 MKClusterAnnotation
方法。但它试图在您的 CustomPinAnnotation
对象上调用该方法。在某个地方,它试图在预期 MKClusterAnnotation
.
的上下文中使用 CustomPinAnnotation
我无法证明你的问题,我不确定你分享的内容是否足够让我们重现它。但我很容易看出它是如何混淆的。注释类型有三种,不仅有MKUserLocation
和CustomPinAnnotation
,还有MKClusterAnnotation
。您的 mapView(_:viewFor:)
只考虑了前两种类型的存在。如果需要,您也可以让它处理 MKClusterAnnotation
:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
} else if annotation is MKClusterAnnotation {
return mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier, for: annotation)
}
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation)
guard
let markerAnnotationView = annotationView as? MKMarkerAnnotationView,
let annotation = annotation as? CustomPinAnnotation
else {
return annotationView
}
markerAnnotationView.clusteringIdentifier = annotation.clusteringIdentifier
markerAnnotationView.displayPriority = .required
// markerAnnotationView.glyphText = annotation.glyphText
markerAnnotationView.glyphImage = annotation.glyphImage
markerAnnotationView.glyphTintColor = annotation.glyphTintColor
markerAnnotationView.markerTintColor = annotation.markerTintColor
return markerAnnotationView
}
不过,就我个人而言,我建议完全删除 mapView(_:viewFor:)
,而是定义您自己的注释视图 class 来执行此配置:
class CustomAnnotationView: MKMarkerAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
update(for: annotation)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var annotation: MKAnnotation? { didSet { update(for: annotation) } }
func update(for annotation: MKAnnotation?) {
displayPriority = .required
guard let annotation = annotation as? CustomPinAnnotation else { return }
clusteringIdentifier = annotation.clusteringIdentifier
// markerAnnotationView.glyphText = annotation.glyphText
glyphImage = annotation.glyphImage
glyphTintColor = annotation.glyphTintColor
markerTintColor = annotation.markerTintColor
}
}
当然,请务必注册它(以及您的集群注释视图):
mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)
但关键是 mapView(_:viewFor:)
的默认实现会自动处理所有三种类型的注释视图。通过这种方式,我们将坚韧不拔的“我如何呈现此注释视图”代码从视图控制器(或任何 MKMapViewDelegate
是)中取出并放入它所属的注释视图 class 中。
enter image description here
在地图上显示标注时,可以构建并执行,但是执行过程中出错,停止了。 MKMarkerAnnotationView 显示聚类和字形图像。 大约有100个注解,在加载View的时候从Firestore获取并存储在一个数组中。 放大或移动地图时发生错误。 Swift 版本:Swift5 我也检查了插座连接,但看起来没有问题。
找不到解决办法,你能告诉我哪里出了问题吗? 写了Map等的设置方法,如果从根本上说错了,还望指教
错误 [XXX.CustomPinAnnotation memberAnnotations]:无法识别的选择器发送到实例 0x2835e16c0
- 由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'-[XXX.CustomPinAnnotation memberAnnotations]:无法识别的选择器发送到实例 0x2835e16c0' * 首先抛出调用堆栈:
CustomPinAnnotation.swift
import UIKit
import MapKit
class CustomPinAnnotation: NSObject, MKAnnotation {
let clusteringIdentifier : String
let title: String?
let subtitle: String?
let coordinate: CLLocationCoordinate2D
//let glyphText: String
let glyphImage: UIImage
let glyphTintColor: UIColor
let markerTintColor: UIColor
let objectid: Int
init(_ clusteringIdentifier: String, title: String, subtitle: String, coordinate: CLLocationCoordinate2D, glyphImage: UIImage, glyphTintColor: UIColor, markerTintColor: UIColor, objectid: Int) {
self.clusteringIdentifier = clusteringIdentifier
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
// self.glyphText = glyphText
self.glyphImage = glyphImage
self.glyphTintColor = glyphTintColor
self.markerTintColor = markerTintColor
self.objectid = objectid
}
}
ViewController.swift
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
var locationManager = CLLocationManager()
var userCoordinate = CLLocationCoordinate2D()
//object array
var objectAll = [objectData]()
//Map view
@IBOutlet weak var mapView: MKMapView!
func displayAllMountains() {
for mountain in objectAll {
let pinImage = UIImage.init(named: "XXXXX")!
let subtitletext = String(object.height) + "m"
let annotation = CustomPinAnnotation("clusterid", title:object.name, subtitle: subtitletext, coordinate: object.geopoint, glyphImage: pinImage, glyphTintColor: .white, markerTintColor: .darkGray, objectid: object.objectid)
self.mapView.addAnnotation(annotation)
}
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation === mapView.userLocation {
return nil
} else {
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation)
guard let markerAnnotationView = annotationView as? MKMarkerAnnotationView,
let annotation = annotation as? CustomPinAnnotation else {
return annotationView
}
markerAnnotationView.clusteringIdentifier = annotation.clusteringIdentifier
// markerAnnotationView.glyphText = annotation.glyphText
markerAnnotationView.glyphImage = annotation.glyphImage
markerAnnotationView.glyphTintColor = annotation.glyphTintColor
markerAnnotationView.markerTintColor = annotation.markerTintColor
return markerAnnotationView
}
}
}
你说它在报告:
Error [XXX.CustomPinAnnotation memberAnnotations]: unrecognized selector sent to instance 0x2835e16c0
memberAnnotations
是一种 MKClusterAnnotation
方法。但它试图在您的 CustomPinAnnotation
对象上调用该方法。在某个地方,它试图在预期 MKClusterAnnotation
.
CustomPinAnnotation
我无法证明你的问题,我不确定你分享的内容是否足够让我们重现它。但我很容易看出它是如何混淆的。注释类型有三种,不仅有MKUserLocation
和CustomPinAnnotation
,还有MKClusterAnnotation
。您的 mapView(_:viewFor:)
只考虑了前两种类型的存在。如果需要,您也可以让它处理 MKClusterAnnotation
:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
} else if annotation is MKClusterAnnotation {
return mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier, for: annotation)
}
let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation)
guard
let markerAnnotationView = annotationView as? MKMarkerAnnotationView,
let annotation = annotation as? CustomPinAnnotation
else {
return annotationView
}
markerAnnotationView.clusteringIdentifier = annotation.clusteringIdentifier
markerAnnotationView.displayPriority = .required
// markerAnnotationView.glyphText = annotation.glyphText
markerAnnotationView.glyphImage = annotation.glyphImage
markerAnnotationView.glyphTintColor = annotation.glyphTintColor
markerAnnotationView.markerTintColor = annotation.markerTintColor
return markerAnnotationView
}
不过,就我个人而言,我建议完全删除 mapView(_:viewFor:)
,而是定义您自己的注释视图 class 来执行此配置:
class CustomAnnotationView: MKMarkerAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
update(for: annotation)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var annotation: MKAnnotation? { didSet { update(for: annotation) } }
func update(for annotation: MKAnnotation?) {
displayPriority = .required
guard let annotation = annotation as? CustomPinAnnotation else { return }
clusteringIdentifier = annotation.clusteringIdentifier
// markerAnnotationView.glyphText = annotation.glyphText
glyphImage = annotation.glyphImage
glyphTintColor = annotation.glyphTintColor
markerTintColor = annotation.markerTintColor
}
}
当然,请务必注册它(以及您的集群注释视图):
mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)
但关键是 mapView(_:viewFor:)
的默认实现会自动处理所有三种类型的注释视图。通过这种方式,我们将坚韧不拔的“我如何呈现此注释视图”代码从视图控制器(或任何 MKMapViewDelegate
是)中取出并放入它所属的注释视图 class 中。