Make your custom annotation view
There is no public API allowing you to access the label in the pop up directly. What you need to do is make a subclass of MKPinAnnotationView
and do whatever customization you want there. As an example,
class CustomAnnotationView : MKPinAnnotationView
{
let selectedLabel:UILabel = UILabel.init(frame:CGRectMake(0, 0, 140, 38))
override func setSelected(selected: Bool, animated: Bool)
{
super.setSelected(false, animated: animated)
if(selected)
{
// Do customization, for example:
selectedLabel.text = "Hello World!!"
selectedLabel.textAlignment = .Center
selectedLabel.font = UIFont.init(name: "HelveticaBold", size: 15)
selectedLabel.backgroundColor = UIColor.lightGrayColor()
selectedLabel.layer.borderColor = UIColor.darkGrayColor().CGColor
selectedLabel.layer.borderWidth = 2
selectedLabel.layer.cornerRadius = 5
selectedLabel.layer.masksToBounds = true
selectedLabel.center.x = 0.5 * self.frame.size.width;
selectedLabel.center.y = -0.5 * selectedLabel.frame.height;
self.addSubview(selectedLabel)
}
else
{
selectedLabel.removeFromSuperview()
}
}
}
Other Notes
Use this custom view in the map view:
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
var anno = mapView.dequeueReusableAnnotationViewWithIdentifier("Anno")
if anno == nil
{
anno = CustomAnnotationView.init(annotation: annotation, reuseIdentifier: "Anno")
}
return anno;
}
Since the title
property of the annotation is not set, you will have to call the map view function selectAnnotation
yourself. Add the following to the CustomAnnotationView
class:
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
mapView?.selectAnnotation(self.annotation!, animated: true)
}
If you want to have more than one marker on the map:
Usually just draw the annotation simply during initialization. In setSelected just return false (meaning "show all annotations all the time").
class DotAnnotationView : MKPinAnnotationView {
let dot: UILabel = UILabel.init(frame:CGRect(x: 0, y: 0, width: 20, height: 20))
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
_setup()
}
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
_setup()
}
override func prepareForReuse() {
dot.text = "you forgot to set the text value?"
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(false, animated: animated)
}
func _setup() {
dot.textAlignment = .center
.. etc
}
}
You set the string (or other values - say color of the panel) for each annotation in mapView#viewFor. It's like populating a cell in a UITableView.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let textForThisItem = annotation.title!!
// or, just use index#of to determine which row this is in your data array
if annotation.isEqual(mkMap.userLocation) {
// skip the user-position indicator
return nil
}
var anno = mapView.dequeueReusableAnnotationView(withIdentifier: "anno")
if anno == nil {
anno = DotAnnotationView.init(annotation: annotation, reuseIdentifier: "anno")
}
(anno as! DotAnnotationView).dot.text = textForThisItem
return anno
}
Finally note that somewhat confusingly, if you very simply change the class of CustomAnnotationView from MKPinAnnotationView to MKAnnotationView, everything works the same but it replaces "all of the pin" rather than just the annotation.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…