iOS 百度地圖2-定位,自定義標(biāo)注

地圖的定位需要使用 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)了。

定位.PNG

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)

模擬器定位.jpeg

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;
}
自定義標(biāo)注.PNG

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;
}
自定義氣泡.PNG

我們什么時(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傳給他,后面的操作和上面的步驟一樣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容