如您所知,标准 MapKit 标注有一个标题以及左右附件视图,您似乎已经发现标注的标题在截断之前可以显示的文本量有限,而我们没有似乎可以访问标签视图来更改它。
如果您能够以 iOS 9 及更高版本为目标,则还有一个额外的detailCalloutAccessoryView
显示在标题下方。不幸的是,您不能只将标题留空并将所有文本放入详细视图中,因为这样点击时标注根本不会打开,因此您需要将某种文本放入标题中。
如果您无法让它工作或者您需要支持 iOS 8,那么您需要进行自定义标注。这并没有那么困难。创建一个MKAnnotationView
具有您想要的标注外观的子类,然后当您检测到正在点击的标记时mapView(_:didSelectAnnotationView:)
在与标记相同的位置添加特殊标注注释。
这是一种方法:
class MyAnnotation: NSObject, MKAnnotation
{
var coordinate: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 49.5, longitude: -123.0)
var title: String? = " "
}
class CalloutAnnotation: MyAnnotation { } // Special annotation class for the callout
let calloutRect = CGRect(origin: CGPointZero, size: CGSize(width: 200, height: 100))
class CalloutAnnotationView: MKAnnotationView
{
var label: UILabel
init()
{
label = UILabel(frame: CGRectInset(calloutRect, 8.0, 8.0))
label.textAlignment = .Center
label.numberOfLines = 0
super.init(frame: calloutRect)
self.addSubview(label)
self.backgroundColor = UIColor.whiteColor()
self.centerOffset = CGPoint(x: 0.0, y: -(calloutRect.size.height / 2))
self.layer.cornerRadius = 6.0
}
required init?(coder aDecoder: NSCoder)
{
label = UILabel(frame: CGRectInset(calloutRect, 8.0, 8.0))
super.init(coder: aDecoder)
}
}
class ViewController: UIViewController, MKMapViewDelegate
{
let calloutAnnotation = CalloutAnnotation()
@IBOutlet weak var mapView: MKMapView!
override func viewWillAppear(animated: Bool)
{
super.viewWillAppear(animated)
mapView.addAnnotation(MyAnnotation())
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
{
if annotation is CalloutAnnotation
{
let calloutView = CalloutAnnotationView()
calloutView.label.text = "This is a custom callout that can look however you want."
return calloutView
}
else
{
let reuseIdentifier = "pinView"
let pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseIdentifier) ??
MKAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
pinView.image = UIImage(named: "Pin")
pinView.canShowCallout = false
return pinView
}
}
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView)
{
if let coordinate = view.annotation?.coordinate
{
calloutAnnotation.coordinate = coordinate
mapView.addAnnotation(calloutAnnotation)
}
}
func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView)
{
mapView.removeAnnotation(calloutAnnotation)
}
}
该视图只是一个常规视图,可以响应触摸等。这仍然不完美,因为当标注出现时您会丢失“弹出”动画,但如果需要,您可以通过更多工作将其添加回来。我还没有尝试过,但我确实在某一时刻出现了动画淡入淡出的情况,所以我相当确定这是可能的。