adding/removing 注释时奇怪的自定义注释行为
Weird custom annotation behaviour when adding/removing annotations
我正在为 iOS 开发应用程序,并且在我的地图视图上遇到了自定义注释的问题。
思路如下:
1) 我将用户位置加载到地图中,从该位置向我的后端服务器发送请求以检索所有附近的兴趣点。
2) 我有一个自定义注解如下:
class CustomPointAnnotation: MKPointAnnotation {
var imageName: String?
var activeImageName : String?
var trainCrossingId : Int?
var notificationCount : UILabel = UILabel()
var labelIsHidden : Bool = true
}
当我将注释添加到地图上时,我正在动态设置 notificationCount
标签以使用我从 Firebase 数据库中检索到的数据。
3) 用户能够 increase/decrease 当前位置周围半径的大小。选择这个新的半径后,我使用 mapView.removeAnnotations(mapView.annotations)
删除所有注释,然后使用使用所选半径从服务器检索到的新数据重新添加这些注释。
问题:
最初加载视图时,注释按预期工作,并设置了正确的标签等。
但是,一旦用户更新了半径并且我 remove/add 以前的注释,注释及其对应的标签就没有按预期显示。
例如,这是第一次进入视图时地图的样子:
然后一旦我改变了半径的大小:
预期数据是初始图像中显示的数据(首次进入视图时),但是更新半径时,我的注释的 z 值未得到遵守,notificationCount
不正确(例如,第二张图中的第三点不应该有标签)。这很奇怪,因为我已经设置了打印语句和断点来监视 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {...}
中的每个注释并且值是正确的并且符合我的期望,但是视图没有显示这些值。
关于这里可能出了什么问题的任何想法?提前致谢!
编辑以包含以下 mapView 委托:
// Custom annotation view
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if !(annotation is CustomPointAnnotation) {
return nil
}
let reuseId = "trainPin"
var anView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
}
else {
anView?.annotation = annotation
}
let cpa = annotation as! CustomPointAnnotation
let icon : UIImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 32, height: 32))
icon.image = UIImage(named:cpa.imageName)
icon.layer.zPosition = 1
anView?.rightCalloutAccessoryView = cpa.annotationButton
anView?.addSubview(cpa.notificationCount)
anView?.addSubview(icon)
anView?.frame = CGRect(x: 0, y:0, width:32, height:32)
anView?.canShowCallout = true
return anView
}
我相信随着 anView
将被重用,视图将有许多子视图,因为您删除和添加注释。尝试先删除子视图然后再添加:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if !(annotation is CustomPointAnnotation) {
return nil
}
let reuseId = "trainPin"
var anView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
}
else {
anView?.annotation = annotation
}
let cpa = annotation as! CustomPointAnnotation
let icon : UIImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 32, height: 32))
icon.image = UIImage(named:cpa.imageName)
icon.layer.zPosition = 1
anView?.rightCalloutAccessoryView = cpa.annotationButton
for view in anView?.subviews {
view.removeFromSuperView()
}
anView?.addSubview(cpa.notificationCount)
anView?.addSubview(icon)
anView?.frame = CGRect(x: 0, y:0, width:32, height:32)
anView?.canShowCallout = true
return anView
}
我正在为 iOS 开发应用程序,并且在我的地图视图上遇到了自定义注释的问题。
思路如下:
1) 我将用户位置加载到地图中,从该位置向我的后端服务器发送请求以检索所有附近的兴趣点。
2) 我有一个自定义注解如下:
class CustomPointAnnotation: MKPointAnnotation {
var imageName: String?
var activeImageName : String?
var trainCrossingId : Int?
var notificationCount : UILabel = UILabel()
var labelIsHidden : Bool = true
}
当我将注释添加到地图上时,我正在动态设置 notificationCount
标签以使用我从 Firebase 数据库中检索到的数据。
3) 用户能够 increase/decrease 当前位置周围半径的大小。选择这个新的半径后,我使用 mapView.removeAnnotations(mapView.annotations)
删除所有注释,然后使用使用所选半径从服务器检索到的新数据重新添加这些注释。
问题:
最初加载视图时,注释按预期工作,并设置了正确的标签等。
但是,一旦用户更新了半径并且我 remove/add 以前的注释,注释及其对应的标签就没有按预期显示。
例如,这是第一次进入视图时地图的样子:
然后一旦我改变了半径的大小:
预期数据是初始图像中显示的数据(首次进入视图时),但是更新半径时,我的注释的 z 值未得到遵守,notificationCount
不正确(例如,第二张图中的第三点不应该有标签)。这很奇怪,因为我已经设置了打印语句和断点来监视 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {...}
中的每个注释并且值是正确的并且符合我的期望,但是视图没有显示这些值。
关于这里可能出了什么问题的任何想法?提前致谢!
编辑以包含以下 mapView 委托:
// Custom annotation view
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if !(annotation is CustomPointAnnotation) {
return nil
}
let reuseId = "trainPin"
var anView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
}
else {
anView?.annotation = annotation
}
let cpa = annotation as! CustomPointAnnotation
let icon : UIImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 32, height: 32))
icon.image = UIImage(named:cpa.imageName)
icon.layer.zPosition = 1
anView?.rightCalloutAccessoryView = cpa.annotationButton
anView?.addSubview(cpa.notificationCount)
anView?.addSubview(icon)
anView?.frame = CGRect(x: 0, y:0, width:32, height:32)
anView?.canShowCallout = true
return anView
}
我相信随着 anView
将被重用,视图将有许多子视图,因为您删除和添加注释。尝试先删除子视图然后再添加:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if !(annotation is CustomPointAnnotation) {
return nil
}
let reuseId = "trainPin"
var anView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
}
else {
anView?.annotation = annotation
}
let cpa = annotation as! CustomPointAnnotation
let icon : UIImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 32, height: 32))
icon.image = UIImage(named:cpa.imageName)
icon.layer.zPosition = 1
anView?.rightCalloutAccessoryView = cpa.annotationButton
for view in anView?.subviews {
view.removeFromSuperView()
}
anView?.addSubview(cpa.notificationCount)
anView?.addSubview(icon)
anView?.frame = CGRect(x: 0, y:0, width:32, height:32)
anView?.canShowCallout = true
return anView
}