为什么要把这个拿出来单独写呢,因为标注是地图开发中经常用到的东西,而且需求各种各样,提供的默认标注不足以满足需求。在百度地图的官方文档里面也没有很详细的说明,就把自己的使用心得拿出来记录一下。
首先,要理清楚他们之间的关系。
参考一下百度的类继承关系:
http://wiki.lbsyun.baidu.com/cms/iossdk/doc/v2_8_0/html/hierarchy.html
可以看到,BMKPinAnnotationView继承的BMKAnnotationView,然后BMKActionPaopaoView、BMKAnnotationView和BMKMapView都是继承的UIVIew,属于同一级别。
然后就是标注点,其实就是协议,想要添加标注,就必须实现协议。
一般的,我们去创建一个BMKPointAnnotation对象,然后给这个对象的coordinate赋值,coordinate是一个CLLocationCoordinate2D对象,就是坐标点。这样就能在地图上确定位置了。同时还有一个title和subtitle ,设置上这两个属性就会有气泡了,但是气泡的显示还需要在View里面设置的,请继续往先看。
这里引入一段代码:
/**
* 初始化一个标注
* 注意:一定要在设置代理之后去添加,不然不会走代理方法,这样就会显示一个默认标注,没有自定义效果了
*/
- (void)initAnnotataion{
BMKPointAnnotation *annotation = [[BMKPointAnnotation alloc]init];
annotation.coordinate = CLLocationCoordinate2DMake(39.915, 116.404);
annotation.title = @"我在这里ARFAA~~~";
annotation.subtitle = @"SS";
//在地图上添加Annotation后才会有标注
[self.mapView addAnnotation:annotation];
}
这里可以进行自定义,自定义的只要继承了BMKPointAnnotation就行,然后自己添加一些属性方法之类的,这里就不细说了。
添加完标注,接下来就要走代理方法了。 先看代码
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
{
//这是错误的,放在这里警示一下
if ([annotation isKindOfClass:[BMKUserLocation class]]) {
BMKPinAnnotationView *newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"myAnnotation"];
newAnnotationView.pinColor = BMKPinAnnotationColorPurple;
newAnnotationView.animatesDrop = YES;// 设置该标注点动画显示
return newAnnotationView;
}
//这是正确的写法
if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
//设置复用
CustomAnnotationView *pointAnnotation = (CustomAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"identifier"];
if (!pointAnnotation)
{
pointAnnotation = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"identifier"];
}
//动画效果
//pointAnnotation.animatesDrop = YES;
//可以拖动
pointAnnotation.draggable = YES;
//设置title,选中弹出气泡
pointAnnotation.canShowCallout = YES;
//设置自定义标注图标
pointAnnotation.image = [UIImage imageNamed:@"icon_passenger"];
return pointAnnotation;
}
return nil;
}
在if里面判断一下是否有此标注,如果有,然后进行下一步。还有一点,如果使用了自定义的标注,最好是判断自定义的类,而不是判断BMKPointAnnotation。因为在之后的话,要使用到这个对象需要强转,父类强转子类对象如果不一致,会崩溃的。
定位其实也是一种标注,在其他地图里是可以这么写的,因为UserLocation会去实现< BMKAnnotation>这个协议,但是百度的没有,猜测可能是在.m中去实现了协议方法。关于如何自定义定位标注,后面再说。
之后我们进行创建View。这个地方我创建了一个自定义的view。自定义的只需要去继承一下BMKPinAnnotationView或者BMKAnnotationView就可以了。之前说过了BMKPinAnnotationView是BMKAnnotationView的子类,继承BMKPinAnnotationView会有默认大头针而已。
我这里自定义的只是为了设置一个自定义泡泡。
- (instancetype)initWithAnnotation:(id<BMKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self) {
self.paopaoView = [[BMKActionPaopaoView alloc]initWithCustomView:self.calloutView];
}
return self;
}
- (CustomCalloutView *)calloutView
{
if (!_calloutView) {
_calloutView = [[CustomCalloutView alloc] initWithFrame:CGRectMake(0, 0, kCalloutWidth, kCalloutHeight)];
}
return _calloutView;
}
-(void)setAnnotation:(id<BMKAnnotation>)annotation
{
[super setAnnotation:annotation];
self.paopaoView = [[BMKActionPaopaoView alloc]initWithCustomView:self.calloutView];
}
这里就是给self.paopaoView赋值而已,没什么特别的。至于CustomCalloutView里面怎么写的,就不详细说明了,其实就是一个View。
这样就完成了自定义标注及气泡。
最后再说一下定位标注。
关于更改定位的样式,百度提供的方式是用mapView设置Param。方法为:
-(void)updateLocationViewWithParam:(BMKLocationViewDisplayParam*)locationViewDisplayParam;
首先创建一个BMKLocationViewDisplayParam对象,设置它的属性。
BMKLocationViewDisplayParam *param = [[BMKLocationViewDisplayParam alloc]init];
param.locationViewImgName = @"icon_nav_waypoint";
[_mapView updateLocationViewWithParam:param];
但是要注意,这里的图片一定要在mapapi.bundle资源文件库里,不然无效。
还有一种办法,定位是可以获取到坐标的,完全可以不用系统给出的定位显示,根据定位的坐标自己创建标注,这样就可以更加灵活的去实现显示。