iOS实现MKMapView地图的自定义CallOut

实现MKMapView地图的自定义CallOut

有三种思路方案来实现需求

一、通过MKAnnotationView自带的callOut来添加

  • canShowCallout
  • leftCalloutAccessoryView
  • rightCalloutAccessoryView

虽然系统的callOutView具有良好的动画交互和提供的AccessoryView来满足一些自定义的需求,但是由于无法更换背景导致一些自定义的需求无法实现。事实证明这种方案不灵活!

self.canShowCallout = YES;

自定callOutView的背景图片:

让我们来看看iOS自带的slicing

水平方向上,会出现三条线,红色线框框住的两条线中间的部分将在图片拉伸时不断复制到图片拉伸部分。最边两侧的图片部分在图片拉伸时则保持不变。

垂直方向也是同样道理,红色线框框住的两条线中间的部分将在图片拉伸时不断复制到图片拉伸部分。上下两侧的图片部分在图片拉伸时则保持不变。

综上所述:

虽然iOS自带slicing,但是根据其使用的定义,也仅仅是在拉伸的时候保护四个角的圆角,无论如何拖线,都无法做到保护箭头,所以在这里callOutView的背景图片无法只用1张图片就完成。

这里我们采用了使用3张图片,分别左、中、右来实现地图的自定义callOutView的背景。

注意:加了这句代码之后,如果不写title将无法弹出callOut

二、 通过mapView的代理回调来添加和删除Annotation来添加

  1. 当调用MKMapViewandAnnotation添加一个annotation时,系统会回调MKMapViewdelegate中的viewForAnnotation方法,返回标记要显示的annotationview

  2. 当点添加的annotation时,系统会调delegate中的didSelectAnnotationView方法,我们再调用addAnnotation添加一个CustomCalloutAnnotation,调了这个方法后,系统又会回调viewForAnnotation方法,我们再返回我们自定义的CustomCalloutView

  3. 在点击地图其他区域位置的时候系统会回调didDeselectAnnotationView方法,然后在这个方法中remove掉之前加到地图上的那个自定义的AnnotationView

综上所述:

这种方法主要是要实现地图的两个代理方法:

top Created with Sketch.