我正在使用iOS 11 MKMarkerAnnotationView创建一个带有地图和100-200 MKPointAnnotation的简单视图控制器
这是控制器的viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
self.mapView.register(StationAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
self.mapView.register(StationClusterView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)
locationDelegate.delegate = self
self.mapView.delegate = self
self.mapView.showsUserLocation = true
self.refreshData()
self.establishUserPosition()
}
然后我从JSON(网络对象)下载电台,然后将所有电台添加到mapview
func reloadViews(){
if let network = network{
for station in network.stations{
let annotation = StationAnnotation(station: station)
annotations.append(annotation) // I add the annotations to an array to prevent them to be deallocated
mapView.addAnnotation(annotation)
}
}
}
这是我的个人注释
class StationAnnotation : MKPointAnnotation{
var station : Station?
var tintColor : UIColor?{
if self.station?.free_bikes ?? 0 > 0 {
return .green
}else{
return .red
}
}
var glyphImage : UIImage?{
if self.station?.extra.status == "online"{
return UIImage(named: "Bicycle")
}else{
return UIImage(named: "Ban")
}
}
override init() {
super.init()
}
convenience init(station : Station){
self.init()
self.title = station.name
self.coordinate = CLLocationCoordinate2D(latitude: station.latitude, longitude: station.longitude)
self.station = station
if station.extra.status == "online"{
self.subtitle = "Bikes: \(station.free_bikes) - Slots: \(station.empty_slots)"
}else{
self.subtitle = station.extra.status
}
}
}
我的习俗观点
class StationAnnotationView : MKMarkerAnnotationView{
override var annotation: MKAnnotation? {
willSet {
if let annotation = newValue as? StationAnnotation{
self.markerTintColor = annotation.tintColor
self.clusteringIdentifier = "station"
self.glyphImage = annotation.glyphImage
}
}
}
}
class StationClusterView: MKAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var annotation: MKAnnotation? {
willSet {
if let cluster = newValue as? MKClusterAnnotation {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 40, height: 40))
let count = cluster.memberAnnotations.count
let onlineCount = cluster.memberAnnotations.filter { member -> Bool in
return (member as! StationAnnotation).station?.extra.status == "online"
}.count
image = renderer.image { _ in
// Fill full circle with tricycle color
UIColor(named: "Forbidden")?.setFill()
UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 40, height: 40)).fill()
// Fill pie with unicycle color
UIColor(named: "Available")?.setFill()
let piePath = UIBezierPath()
piePath.addArc(withCenter: CGPoint(x: 20, y: 20), radius: 20,
startAngle: 0, endAngle: (CGFloat.pi * 2.0 * CGFloat(onlineCount)) / CGFloat(count),
clockwise: true)
piePath.addLine(to: CGPoint(x: 20, y: 20))
piePath.close()
piePath.fill()
// Fill inner circle with white color
UIColor.white.setFill()
UIBezierPath(ovalIn: CGRect(x: 8, y: 8, width: 24, height: 24)).fill()
// Finally draw count text vertically and horizontally centered
let attributes = [ NSAttributedStringKey.foregroundColor: UIColor.black,
NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 20)]
let text = "\(count)"
let size = text.size(withAttributes: attributes)
let rect = CGRect(x: 20 - size.width / 2, y: 20 - size.height / 2, width: size.width, height: size.height)
text.draw(in: rect, withAttributes: attributes)
}
}
}
}
}
我不知道应用程序在捏合,缩放或平移时的原因,使用SIGABRT信号崩溃和此异常
*** Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '*** -[__NSDictionaryM setObject:forKey:]: key cannot be nil'
我尝试过各种调试系统并且使用异常断点没有帮助......你有什么建议吗?
答案 0 :(得分:0)
mapView.register(AnyClass?, forAnnotationViewWithReuseIdentifier: String)
和
mapView.dequeueReusableAnnotationView(withIdentifier: String)
返回nil。
如此热门修复: 添加:
ViewController: UIViewController, MKMapViewDelegate
添加
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
mapView.register(MarkerPointView.self, forAnnotationViewWithReuseIdentifier: "marker")
mapView.register(ClusterView.self, forAnnotationViewWithReuseIdentifier: "cluster")
}
最后:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let marker = annotation as? MarkerAnnotation{
var view = mapView.dequeueReusableAnnotationView(withIdentifier: "marker") as? MarkerPointView
if view == nil {
//Very IMPORTANT
print("nil for Marker")
view = MarkerPointView(annotation: marker, reuseIdentifier: "marker")
}
return view
}else if let cluster = annotation as? MKClusterAnnotation{
var view = mapView.dequeueReusableAnnotationView(withIdentifier: "cluster") as? ClusterView
if view == nil{
//Very IMPORTANT
print("nil for Cluster")
view = ClusterView(annotation: cluster, reuseIdentifier: "cluster")
}
return view
}
else{
return nil
}
}
希望对某人有所帮助,并在接下来的转发苹果修复它,因为我们可以像他们在36:50 wwdc2017上所说的那样使用它 - 我们不能删除它!!!!!!!!