我正在使用mkmapview构建应用。我正在使用自定义注释视图来显示头像和相应的标签。一切正常:每个头像和相应的标签都正确显示。我可以在地图中导航。但是当我最大限度地缩小时,让我们说在旧金山显示4个标签,一旦我恢复到原始比例,标签会重叠。 最大缩小时,标签位于彼此之上。这个是正常的。但是一旦我恢复正常变焦:
let span = MKCoordinateSpanMake(0.001, 0.001)
每个标签看起来都被其他标签盖章:
上面的标签应该说" sanchez"但它与其他标签文本融为一体。
以下是自定义注释视图的代码:
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if !(annotation is MKPointAnnotation) {
return nil
}
var seleccion:Bool
let reuseId = "test"
var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
anView.canShowCallout = true
}
else {
anView.annotation = annotation
}
let cpa = annotation as! CustomPointAnnotation
anView.image = cpa.image
if cpa.toBeTriggered == true {
anView.selected = true
}
var nameLbl: UILabel! = UILabel(frame: CGRectMake(-24, 40, 100, 30))
nameLbl.text = cpa.nickName
nameLbl.textColor = UIColor.blackColor()
nameLbl.font = UIFont(name: "Atari Classic Extrasmooth", size: 10)
nameLbl.textAlignment = NSTextAlignment.Center
anView.addSubview(nameLbl)
return anView
}
这就是它变得奇怪的地方:如果我为nameLbl设置了背景颜色,标签不会重叠/融化。这让我想起了Apple的一个错误......
修改
正如@Anna所提到的,CustomPointAnnotation是一个数据模型类:
import UIKit
import MapKit
class CustomPointAnnotation: MKPointAnnotation {
var image: UIImage!
var toBeTriggered: Bool = false
var selected: Bool = false
var nickName: String!
}
答案 0 :(得分:3)
导致标签重叠的问题有两个:
正如评论中所述,每次调用 UILabel
时,viewForAnnotation
都会添加到注释视图,包括回收视图时( mapView.dequeueReusableAnnotationViewWithIdentifier
返回一个视图)。循环播放的视图已经设置了UILabel
,其中包含文字。当您在其上添加另一个标签时,会出现重叠文本。
不是每次都添加标签,而是仅在实际创建MKAnnotationView
时添加标签(当dequeue
返回nil
时)。然后设置标签text
,获取对视图上已有标签的引用(在其上设置tag
是一种简单的方法。)
另一种方法是创建自定义注释 view 类(MKAnnotationView
的子类)并在其中实现prepareForReuse
并清除标签的文本。此自定义视图类与CustomPointAnnotation
模型类是分开的。
要以最快的方式解决问题1,您可以执行以下操作:
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if !(annotation is CustomPointAnnotation) {
//Check for CustomPointAnnotation (not MKPointAnnotation)
//because the code below assumes CustomPointAnnotation.
return nil
}
var seleccion:Bool
let reuseId = "test"
var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
if anView == nil {
anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
anView.canShowCallout = true
//Create and add UILabel only when actually creating MKAnnotationView...
var nameLbl: UILabel! = UILabel(frame: CGRectMake(-24, 40, 100, 30))
nameLbl.tag = 42 //set tag on it so we can easily find it later
nameLbl.textColor = UIColor.blackColor()
nameLbl.font = UIFont(name: "Atari Classic Extrasmooth", size: 10)
nameLbl.textAlignment = NSTextAlignment.Center
anView.addSubview(nameLbl)
}
else {
anView.annotation = annotation
}
let cpa = annotation as! CustomPointAnnotation
anView.image = cpa.image
//NOTE: Setting selected property directly on MKAnnotationView
// is not recommended.
// See documentation for the property.
// Instead, call MKMapView.selectAnnotation method
// in the didAddAnnotationViews delegate method.
if cpa.toBeTriggered == true {
anView.selected = true
}
//Get a reference to the UILabel already on the view
//and set its text...
if let nameLbl = anView.viewWithTag(42) as? UILabel {
nameLbl.text = cpa.nickName
}
return anView
}
答案 1 :(得分:1)
每次调用
时使用不同的重用标识符 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
取一个计数器变量并将其作为字符串传递给annotationIdentifier
mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier)