地圖的定位需要使用 BMKLocationService這個(gè)類(lèi),并遵循BMKLocationServiceDelegate代理
1 基本定位
1.1 聲明
@property (nonatomic, strong) BMKLocationService *locService;
1.2 在 viewDidLoad 中初始化
_locService = [[BMKLocationService alloc]init];
1.3 同樣設(shè)置代理,管理內(nèi)存
-(void)viewWillAppear:(BOOL)animated
{
[_mapView viewWillAppear];
_mapView.delegate = self; // 此處記得不用的時(shí)候需要置nil,否則影響內(nèi)存的釋放
_locService.delegate = self;
}
-(void)viewWillDisappear:(BOOL)animated
{
[_mapView viewWillDisappear];
_mapView.delegate = nil; // 不用時(shí),置nil
_locService.delegate = nil;
}
1.4 在點(diǎn)擊方法中,啟動(dòng)定位服務(wù)
- (void)position {
//是否顯示定位小藍(lán)點(diǎn),設(shè)置為no不顯示,可以自定義(這里顯示前提要遵循代理方法,不可缺少)
_mapView.showsUserLocation = YES;
//啟動(dòng)LocationService
_mapView.zoomLevel = 14.1; //地圖等級(jí),數(shù)字越大越清晰
_mapView.userTrackingMode = BMKUserTrackingModeNone;//設(shè)定定位模式
[_locService startUserLocationService];
}
1.5 在 BMKLocationService 的代理方法中實(shí)現(xiàn)定位
//用戶位置更新后,會(huì)調(diào)用此函數(shù)
- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation {
NSLog(@"當(dāng)前位置%f,%f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude);
// 顯示定位點(diǎn) 必須設(shè)置地圖的中心點(diǎn),地圖才會(huì)切換顯示到定位位置
_mapView.centerCoordinate = userLocation.location.coordinate;
//設(shè)置縮放比例,不設(shè)置一次,測(cè)試第一次定位時(shí)中心總顯示在天安門(mén)
_mapView.zoomLevel = 14.1;
[_mapView updateLocationData:userLocation];
[_locService stopUserLocationService];
}
此時(shí)就可以定位,并顯示小藍(lán)點(diǎn)了。
2 問(wèn)題處理
過(guò)程中遇到無(wú)法顯示定位小藍(lán)點(diǎn)的問(wèn)題,可能原因:
2.1 info.plist 權(quán)限未加
Privacy - Location When In Use Usage Description 允許App在使用時(shí)獲取GPS的描述
Privacy - Location Always Usage Description 允許永久使用GPS的描述
2.2 若是手動(dòng)導(dǎo)入的SDK,沒(méi)有用cocoapods,檢查有沒(méi)有導(dǎo)入mapapi.bundle,這是百度默認(rèn)的素材包,小藍(lán)點(diǎn)圖片在這里面。
以上真機(jī)測(cè)試就正常了。
2.3 使用模擬器沒(méi)有定位。
重置模擬器。
若還沒(méi)有,則可以嘗試下面操作,將None改為以下任意一項(xiàng)
2.4 使用模擬器位置不準(zhǔn)確,帝都定位到米國(guó),目前沒(méi)有找到方法,歡迎留言補(bǔ)充。
3 自定義標(biāo)注-定位圖片
一般產(chǎn)品都會(huì)要求定位圖片使用自己設(shè)計(jì)的圖片,這是就需要用到自定義標(biāo)注了。
這時(shí)應(yīng)先把系統(tǒng)小藍(lán)點(diǎn)的顯示改NO : _mapView.showsUserLocation = NO;
然后來(lái)區(qū)別2個(gè)類(lèi):
BMKPointAnnotation:官方解釋的是一個(gè)點(diǎn)的標(biāo)注,也就是定位的小藍(lán)點(diǎn)所指代的位置,具有地理的經(jīng)緯度特性。
BMKAnnotationView:官方解釋標(biāo)注視圖,也就是指代那個(gè)位置的小藍(lán)點(diǎn),如果想換圖片,則就應(yīng)該在BMKAnnotationView內(nèi)部添加image。
3.1 切換小藍(lán)點(diǎn)圖片
3.1.1 創(chuàng)建 AnnotionView1 類(lèi) 繼承 BMKAnnotationView,重寫(xiě) initWithAnnotation 方法,在其中實(shí)現(xiàn)自定義UI。
#import <BaiduMapAPI_Map/BMKMapView.h>//只引入所需的單個(gè)頭文件
@interface AnnotionView1 : BMKAnnotationView
@property (nonatomic, strong) UIImageView *bgImageView;
@end
- (id)initWithAnnotation:(id<BMKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {
//--------------------------自定義標(biāo)注視圖-------------------------------
self.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
self.centerOffset = CGPointMake(0, 0);
self.frame = CGRectMake(0, 0, 32, 32);
_bgImageView = [[UIImageView alloc]initWithFrame:self.frame];
_bgImageView.image = [UIImage imageNamed:@"cl_cell_selected"];
[self addSubview:_bgImageView];
//--------------------------------------------------------------------
}
return self;
}
3.1.2 聲明一個(gè) BMKPointAnnotation變量,并在didUpdateBMKUserLocation 中初始化
@property (nonatomic, strong) BMKPointAnnotation *pointAnnotation;
- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation {
NSLog(@"當(dāng)前位置%f,%f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude);
// 顯示定位點(diǎn) 必須設(shè)置地圖的中心點(diǎn),地圖才會(huì)切換顯示到定位位置
_mapView.centerCoordinate = userLocation.location.coordinate;
//設(shè)置縮放比例,不設(shè)置一次,測(cè)試第一次定位時(shí)中心總顯示在天安門(mén)
_mapView.zoomLevel = 14.1;
[_mapView updateLocationData:userLocation];
[_locService stopUserLocationService];
// ------------------自定義標(biāo)注-------------------------------------
_pointAnnotation = [[BMKPointAnnotation alloc]init];
_pointAnnotation.coordinate = userLocation.location.coordinate;
[_mapView addAnnotation:_pointAnnotation];
[_mapView selectAnnotation:_pointAnnotation animated:YES];
// 設(shè)置氣泡內(nèi)容,不設(shè)置則不顯示氣泡
_pointAnnotation.title = @"我在這里";
_pointAnnotation.subtitle = @"公司";
// ----------------------------------------------------------------------
}
3.1.3 實(shí)現(xiàn)生成對(duì)應(yīng)標(biāo)注視圖的代理方法 viewForAnnotation
注意:此方法只有在執(zhí)行了 [_mapView addAnnotation:_pointAnnotation] 后才會(huì)調(diào)用。
static NSString *myLocationViewID = @"myID";
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation {
AnnotionView1 *newAnnotationView = (AnnotionView1 *)[mapView dequeueReusableAnnotationViewWithIdentifier:myLocationViewID];
if (newAnnotationView == nil) {
newAnnotationView = [[AnnotionView1 alloc] initWithAnnotation:annotation reuseIdentifier:myLocationViewID];
}
return newAnnotationView;
}
3.2 自定義氣泡
上圖顯示的 我在這里.. 就是氣泡,點(diǎn)擊地圖其他地方會(huì)消失,點(diǎn)擊定位點(diǎn)會(huì)出現(xiàn),這是系統(tǒng)默認(rèn)的,現(xiàn)在自定義樣式。
paopaoView是BMKAnnotationView的一個(gè)屬性,它就是點(diǎn)擊觸發(fā)的氣泡視圖。在上述重寫(xiě)B(tài)MKAnnotationView的 initWithAnnotation方法中自定義。
- (id)initWithAnnotation:(id<BMKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {
//--------------------------自定義標(biāo)注視圖-------------------------------
self.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
self.centerOffset = CGPointMake(0, 0);
self.frame = CGRectMake(0, 0, 32, 32);
_bgImageView = [[UIImageView alloc]initWithFrame:self.frame];
_bgImageView.image = [UIImage imageNamed:@"cl_cell_selected"];
[self addSubview:_bgImageView];
//--------------------------------------------------------------------
//--------------------------自定義氣泡視圖-------------------------------
UIImageView *paoImg = [[UIImageView alloc] initWithFrame:CGRectMake(0, 13, 24, 24)];
paoImg.image =[UIImage imageNamed:@"tabbar_shouye_selected"];
UILabel *paoLbl = [[UILabel alloc]initWithFrame:CGRectMake(30, 0, 70, 50)];
paoLbl.text = @"御書(shū)房";
paoLbl.textColor = [UIColor whiteColor];
paoLbl.font = [UIFont systemFontOfSize:15];
UIView *paopao = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 50)];
paopao.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7];
[paopao addSubview:paoImg];
[paopao addSubview:paoLbl];
self.paopaoView = [[BMKActionPaopaoView alloc]initWithCustomView:paopao];
//--------------------------------------------------------------------
}
return self;
}
我們什么時(shí)候重寫(xiě)B(tài)MKPointAnnotation呢,一般來(lái)說(shuō)他只是傳個(gè)地理位置信息,當(dāng)我們?cè)诘貓D上想要顯示多個(gè)地理位置信息的時(shí)候,比如后臺(tái)返回來(lái)一個(gè)數(shù)組,里面每個(gè)元素都是一個(gè)字典,每個(gè)字典代表一個(gè)單位,除了地理位置信息,還有其他信息,比如名字,圖片等,對(duì)應(yīng)的是每個(gè)地理位置,這時(shí)候重寫(xiě)B(tài)MKPointAnnotation,并在其中定義一個(gè)model屬性,用來(lái)接收后臺(tái)返回來(lái)的model信息串。然后聲明這個(gè)pointAnnotation類(lèi)的對(duì)象,并給他賦值后臺(tái)返回來(lái)的model信息串中的位置信息,并將整個(gè)model傳給他,后面的操作和上面的步驟一樣。