本文基于一个百度地图上的需求实现,记录下百度地图使用中的点滴,后续会持续更新。
地图上自定义可点击的展示框
需求:在地图上展示区县的数据并可以点击查看下一级区域的数据:
实现的过程:
- 使用百度地图SDK逆向地址解析所有网络返回的地区的经纬度(市级别的地级区在逆向解析的时候,需要加上上一层的市名称,200多个,大部分解析的经纬度是OK的,可是有几个经纬度解析是错误的,需要手动修改过来),存放在一个Plist文件中。
- 根据这个Plist文件中,初始化一个以地区名称为KEY,对应经纬度为Value的Dic
- 根据地名获取到对应的经纬度。
- 根据经纬度初始化对应的BMKPointAnnotation加载到地图上,并把所有的BMKPointAnnotation显示在屏幕中。
由于百度地图自带的BMKAnnotationView 中默认的是大头针,可以设置自定义图片(替换大头针),但是就是无法在地图上放置Label显示文字,本来想让所有大头针的气泡都默认弹出(设置 selected 就行),可是找不到一个方法使所有的气泡都弹出,最后只能自定义一个基于BMKAnnotationView的UIView
#import <BaiduMapAPI_Map/BMKAnnotationView.h>
@protocol myDelegete <NSObject>
- (void)selectAnnotationView:(NSDictionary *)areaDeptDic;
@end
@interface LMCustomAnnotationView : BMKAnnotationView
@property(strong,nonatomic)UILabel *titleLabel;
@property(copy,nonatomic)NSString *deptNo;
@property(weak,nonatomic)id <myDelegete> mydeleget;
@end
#import "LMCustomAnnotationView.h"
@implementation LMCustomAnnotationView
- (id)initWithAnnotation:(id <BMKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier;
{
self = [super init];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.titleLabel = [[MethodTool shareTool] creatLabelWithAttribute:@"" :MEDIUM_FONT :2 :blackC];
[self addSubview:self.titleLabel];
self.titleLabel.sd_layout
.leftSpaceToView(self,Scale_X(0))
.topSpaceToView(self,Scale_Y(5))
.widthRatioToView(self, 1)
.heightIs(30);
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(action)];
[self addGestureRecognizer:tap];
}
return self;
}
- (void)action
{
if (self.titleLabel.text.length>0) {
NSArray *titleA = [self.titleLabel.text componentsSeparatedByString:@":"];
[self.mydeleget selectAnnotationView:@{@"deptName":titleA[0],@"deptNo":self.deptNo}];
}
}
VC中实现百度地图的viewForAnnotation代理
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
{
if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
static NSString *pointReuseIndentifier = @"pointReuseIndentifier";
LMCustomAnnotationView *annotationView = (LMCustomAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndentifier];
if (annotationView == nil) {
annotationView = [[LMCustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndentifier];
annotationView.mydeleget = self;
}
annotationView.titleLabel.text = annotation.title;
annotationView.deptNo = annotation.subtitle;
CGFloat width = [[MethodTool shareTool]getWidthWithString:annotation.title anfont:MEDIUM_FONT];
annotationView.sd_layout.widthIs((width+Scale_X(16))).heightIs(Scale_Y(40));
return annotationView;
}
return nil;
}
最后地图上的点击事件就走的自定义的代理而不是百度的代理
- (void)selectAnnotationView:(NSDictionary *)areaDeptDic
{
NSString *deptNo = areaDeptDic[@"deptNo"];
NSString *deptName = areaDeptDic[@"deptName"];
}
这里说下如何把所有的BMKPointAnnotation显示在屏幕中,并把屏幕边BMKPointAnnotation跟屏幕之间留点白,默认的是四周的BMKPointAnnotation在边上,不会留白的,不太好看。
[self.mapView addAnnotations:self.mapAnimationArray];
[self.mapView showAnnotations:self.mapAnimationArray animated:YES];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.mapView setZoomLevel: (self.mapView.zoomLevel -0.3)]; //这个延迟缩放很精遂
});
其他一些需要注意的点
无法注册?
这种情况下需要更换别的手机号注册才行,就算你之前没有注册过,也不要过于纠结,纠结也没用。
隐藏百度地图的Logo
UIView *mView = mapView.subviews.firstObject;
for (id logoView in mView.subviews)
{
if ([logoView isKindOfClass:[UIImageView class]])
{
UIImageView *b_logo = (UIImageView*)logoView;
b_logo.hidden = YES;
}
}
运行报错:mapai.bundle缺失
运行时出现了这个错误。原因是百度的开发文档里面写的并不正确,导致我添加的是工程外的mapai.bundle,虽然有了勾选“Copy items if needed”复选框,单击“Add”按钮这个情景,但是运行时就报错了。
正确的方法是:需要添加导入工程内的frame中的bundle,而不是工程外面的frame中的bundle,从工程中的Frame中把mapai.bundle添加进工程即可。
didSelectAnnotationView代理函数不会响应。
百度地图在没有设置annotation的title时,点击annotationview不会出现弹出气泡,但是会有一个问题,就是didSelectAnnotationView代理函数不会响应。
要想走didSelectAnnotationView这个代理函数,必须设title值。
如果既想要调用didSelectAnnotationView代理函数,又不想要显示气泡,目前找到一种解决方法是自定义paopaoview
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
newAnnotationView.paopaoView = [[BMKActionPaopaoView alloc] initWithCustomView:view];
关于这个回调,还有一个问题,就是只会响应一次,也就是处于选中状态的annotationview 再次点击时是不会再走这个回调的。
如果还想继续执行这个回调函数,可以在每次在函数的末尾加上
[view setSelected:NO]取消选中状态
点击大头针(自定义视图)、点击大头针上气泡时触发的代理方法
两者是不同的代理
/**
* 当选中一个annotation views时,调用此接口
* @param mapView 地图View
* @param views 选中的annotation views
*/
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view
{
_shopCoor = view.annotation.coordinate;
}
/**
* 选中气泡调用方法
* @param mapView 地图
* @param view annotation
*/
- (void)mapView:(BMKMapView *)mapView annotationViewForBubble:(BMKAnnotationView *)view
{
MyBMKPointAnnotation *tt = (MyBMKPointAnnotation *)view.annotation;
if (tt.shopID) {
BusinessIfonUVC *BusinessIfonVC = [[BusinessIfonUVC alloc]init];
BusinessIfonVC.shopId = tt.shopID;
[self.navigationController pushViewController:BusinessIfonVC animated:YES];
}
}
百度地图中的类继承关系:
知道百度地图SDK中的类继承关系有助于我们了解、使用、自定义设置百度地图。
可看的相关文章
百度地图绘制点标记(大头针)
百度地图深度使用