最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解iOS集成GoogleMap(定位、搜索)

 更新時(shí)間:2018年02月01日 11:49:52   投稿:laozhang  
這篇文章主要介紹了iOS集成GoogleMap(定位、搜索)需要注意的地方,對(duì)此有興趣的讀者一起學(xué)習(xí)下吧。

簡(jiǎn)介:

最近花了些時(shí)間看了GoogleMap官方文件并集成到國(guó)際版app中,網(wǎng)上關(guān)于GoogleMap for iOS的講解相對(duì)Android來(lái)說(shuō)少一點(diǎn),比較有幫助的幾乎全是英文文檔。下面是我開(kāi)發(fā)過(guò)程中遇到的坑、以及采用的解決方法。

集成GoogleMap步驟:

  1. 1、Cocoapods導(dǎo)入pod 'GoogleMaps'
  2. 2、獲取API密匙(前提是已經(jīng)在GoogleMapSDK中創(chuàng)建好自己的應(yīng)用)
  3. 3、配置plist文件搭建定位環(huán)境
  4. 4、調(diào)用代理方法實(shí)現(xiàn)需求

tips:pod 'GoogleMaps'、pod 'GooglePlaces'、pod 'GooglePlacePicker'這三個(gè)框架。(GoogleMaps:顯示基本的定位功能;GooglePlaces:實(shí)現(xiàn)搜索功能,官方文檔叫做地點(diǎn)自動(dòng)完成;GooglePlacePicker:是實(shí)現(xiàn)獲取某個(gè)POI的的詳細(xì)信息,比如名字、詳細(xì)地址、路線等)

景點(diǎn)(POI)包括公園、學(xué)校和政府大樓,等等。 另外,如果地圖類型為 kGMSTypeNormal,商家景點(diǎn)默認(rèn)將顯示在地圖上。 商家景點(diǎn)表示商店、餐館和酒店之類的商家。

按照 Google Places API 中的定義,一個(gè) POI 對(duì)應(yīng)于一個(gè)地點(diǎn)。 例如,休閑公園為景點(diǎn),但噴泉之類的地點(diǎn)通常不屬于景點(diǎn)(除非它們具有國(guó)家或歷史意義)。

配置plist文件:

打開(kāi)plist的代碼源文件,輸入:

定位:

一、在AppDelegate 頭文件 導(dǎo)入框架

#import

二、向您的 application:didFinishLaunchingWithOptions: 方法添加以下內(nèi)容,使用我們剛才獲取到的 API 密鑰替代 YOUR_API_KEY:

[GMSServices provideAPIKey:@"YOUR_API_KEY"];

tips:這一步是在啟動(dòng)app的時(shí)候,GoogleMap準(zhǔn)備代理工作。

三、在我們需要顯示地圖的控制器調(diào)用API方法

@property (nonatomic,strong) CLLocationManager *locationManager;//地圖定位對(duì)象
@property (nonatomic,strong) GMSMapView *mapView;//地圖
@property (nonatomic,strong) GMSMarker *marker;//大頭針
@property (nonatomic,strong) GMSPlacesClient * placesClient;//可以獲取某個(gè)地方的信息
//注冊(cè)的代理
@interface TestMapViewController ()

tips:這是在控制器.h文件聲明的屬性。

(一)初始化一個(gè)地圖對(duì)象

GMSMapView:是控制地圖的外觀類

GMSCameraPosition:是控制地圖要顯示的內(nèi)容類

GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-23.12960481 longitude:113.30887721            zoom:Level];
 self.mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
 self.mapView.delegate = self; //注冊(cè)代理屬性
 self.mapView.settings.compassButton = YES;//顯示指南針
 [self.view addSubview:self.mapView];

tips:上面的經(jīng)緯度可以隨便傳一個(gè),之后會(huì)獲取到新的經(jīng)緯度并更新位置

(二)初始化一個(gè)定位管理者對(duì)象

if (self.locationManager == nil) {
  self.locationManager = [[CLLocationManager alloc]init];
 }
 self.locationManager.delegate = self;
 [self.locationManager requestAlwaysAuthorization];//授權(quán)方式,如果在后臺(tái)也需要定位,那就選擇 requestAlwaysAuthorization。
 self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;//最精確的定位
 self.locationManager.distanceFilter = kCLDistanceFilterNone; // 默認(rèn)是kCLDistanceFilterNone,也可以設(shè)置其他值,表示用戶移動(dòng)的距離小于該范圍內(nèi)就不會(huì)接收到通知
 [self.locationManager startUpdatingLocation];

tips:CLLocationManager 是負(fù)責(zé)獲取用戶行為的類,列如獲取用戶當(dāng)前位置信息。更多詳細(xì)信息請(qǐng)閱覽CLLocationManager。里面講解CLLocationManager的一些應(yīng)用場(chǎng)景并有代碼實(shí)例。

運(yùn)行app:這時(shí)候我們會(huì)看到并沒(méi)有實(shí)景地圖出來(lái),原因是:前面提到的GMSCameraPosition類,我們并沒(méi)有在定位成功之后將定位內(nèi)容賦它。

GMSCameraPosition類,它是負(fù)責(zé)顯示定位內(nèi)容的。很重要!

(三)在定位成功的API代理方法中,獲取經(jīng)緯度并轉(zhuǎn)成影像賦值

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
 CLLocation *curLocation = [locations lastObject];
 // 通過(guò)location 或得到當(dāng)前位置的經(jīng)緯度
 CLLocationCoordinate2D curCoordinate2D = curLocation.coordinate;
 GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:curCoordinate2D.latitude longitude:curCoordinate2D.longitude zoom:Level];
 CLLocationCoordinate2D position2D = CLLocationCoordinate2DMake(curLocation.coordinate.latitude, curLocation.coordinate.longitude);
 self.mapView.camera = camera;//這句話很重要很重要,將我們獲取到的經(jīng)緯度轉(zhuǎn)成影像并賦值給地圖的camera屬性
 [self.locationManager stopUpdatingLocation];//定位成功后停止定位
}

tips:locationManager: didUpdateLocations: 代理方法是GoogleMap 中實(shí)現(xiàn)定位成功后回調(diào)的代理方法,你可以在這里獲取到經(jīng)緯度。

運(yùn)行app:這時(shí)候地圖就出來(lái)了

添加大頭針

GMSMarker類是負(fù)責(zé)顯示大頭針,默認(rèn)是紅色,你可以自定義大頭針,用圖片或者改變顏色,具體看官方文檔GMSMarker。

 self.marker = [GMSMarker markerWithPosition:position2D];
 self.marker.map = self.mapView;

tips:position2D是在定位成功之后轉(zhuǎn)換得到的CLLocationCoordinate2D屬性經(jīng)緯度值。

小坑提示:這時(shí)候有可能會(huì)出現(xiàn),定位成功之后出現(xiàn)多個(gè)大頭針。原因是:進(jìn)行定位的時(shí)候,map獲取多個(gè)預(yù)測(cè)位置,從而產(chǎn)生生成多個(gè)大頭針的現(xiàn)象。解決辦法:在每次生成大頭針之前先清除之前的那個(gè),只生成最精準(zhǔn)的最后一個(gè)。

[self.marker.map clear];
 self.marker.map = nil;

反編碼(經(jīng)緯度轉(zhuǎn)成具體位置):

 CLGeocoder *geocoder = [[CLGeocoder alloc]init];
 //反地理編碼
 [geocoder reverseGeocodeLocation:curLocation completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) {
   
  if (error) {
  }else{
   
    CLPlacemark *placemark = [placemarks objectAtIndex:0];//第一個(gè)位置是最精確的
    //賦值詳細(xì)地址
    DLog(@"placemark---路號(hào)name:%@-市l(wèi)ocality:%@-區(qū)subLocality:%@-省administrativeArea:%@-路thoroughfare:%@",placemark.name,placemark.locality,placemark.subLocality,placemark.administrativeArea,placemark.thoroughfare);
   
  }];

這時(shí)候就已經(jīng)可以獲取到具體的國(guó)家、省、市、區(qū)、街道了。

補(bǔ)充:反編碼是獲取不到POI位置的(我獲取不到)。這時(shí)候可以使用

self.placesClient = [GMSPlacesClient sharedClient];//獲取某個(gè)地點(diǎn)的具體信息
 [self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {
  if (error != nil) {
   DLog(@"Current Place error %@", [error localizedDescription]);
   return;
  }
   
//  for (GMSPlaceLikelihood *likelihood in likelihoodList.likelihoods) {
//   GMSPlace* place = likelihood.place;
//   NSLog(@"Current Place name %@ at likelihood %g", place.name, likelihood.likelihood);
//   NSLog(@"Current Place address %@", place.formattedAddress);
//   NSLog(@"Current Place attributions %@", place.attributions);
//   NSLog(@"Current PlaceID %@", place.placeID);
//  }
   //這里就可以獲取到POI的名字了
   //這里做一些你想做的事
   
 }];

點(diǎn)擊地圖并移動(dòng)大頭針

這里是用到GMSMapViewDelegate的代理回調(diào)

回調(diào)1:這里是點(diǎn)擊地圖上的某個(gè)點(diǎn)API返回的代理方法,在這個(gè)代理方法,你可以獲取經(jīng)緯度去反編譯地址

- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D)coordinate{
 //點(diǎn)擊一次先清除上一次的大頭針
 [self.marker.map clear];
 self.marker.map = nil;
 // 通過(guò)location 或得到當(dāng)前位置的經(jīng)緯度
 GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:coordinate.latitude longitude:coordinate.longitude zoom:Level];
 CLLocationCoordinate2D position2D = CLLocationCoordinate2DMake(coordinate.latitude,coordinate.longitude);
 self.mapView.camera = camera;
 //大頭針
 self.marker = [GMSMarker markerWithPosition:position2D];
 self.marker.map = self.mapView;
 CLLocation *curLocation = [[CLLocation alloc]initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
  
 CLGeocoder *geocoder = [[CLGeocoder alloc]init];
 //反地理編碼
 [geocoder reverseGeocodeLocation:curLocation completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) {
   
  if (error) {
    
   DLog(@"error.description:%@",error.description);
    
  }else{
    
   CLPlacemark *placemark = [placemarks objectAtIndex:0];
    
   //賦值詳細(xì)地址
   DLog(@"placemark---路號(hào)name:%@-市l(wèi)ocality:%@-區(qū)subLocality:%@-省administrativeArea:%@-路thoroughfare:%@",placemark.name,placemark.locality,placemark.subLocality,placemark.administrativeArea,placemark.thoroughfare); 
 }]; 
}

回調(diào)2:這里也是點(diǎn)擊地圖上的某個(gè)點(diǎn)API返回的代理方法

- (void)mapView:(GMSMapView *)mapView
didTapPOIWithPlaceID:(NSString *)placeID
   name:(NSString *)name
  location:(CLLocationCoordinate2D)location{
}

tips:值得注意的,兩者的區(qū)別是:第二個(gè)點(diǎn)擊代理方法是當(dāng)你點(diǎn)擊POI的時(shí)候才會(huì)回調(diào),會(huì)返回place的name、ID、經(jīng)緯度;第一個(gè)代理方法是只要點(diǎn)擊地圖任意一個(gè)位置就會(huì)回調(diào),只會(huì)返回經(jīng)緯度。也就是:每一次的點(diǎn)擊,只會(huì)執(zhí)行其中一個(gè)代理方法。

搜索:

搜索功能在官方文檔是叫做“自動(dòng)完成”,即你輸入一部分的文本,GoogleMap會(huì)根據(jù)你的文本預(yù)測(cè)出地點(diǎn)并自動(dòng)填充返回,具體請(qǐng)看官方文檔自動(dòng)完成

效果如圖:

這里你需要做的步驟跟做“定位”的一樣:

(1)獲取APIKEY

(2) 在application:didFinishLaunchingWithOptions: 注冊(cè)密匙

1[GMSPlacesClient provideAPIKey:@"YOUR_API_KEY"];

(3) 創(chuàng)建搜索UI并調(diào)用代理方法獲取API自動(dòng)填充的結(jié)果數(shù)組集

小坑提示: GMSPlacesClient跟GMSServices的密匙是不一樣的,密匙不對(duì)的話,會(huì)出現(xiàn)反復(fù)調(diào)用

viewController:didFailAutocompleteWithError:的現(xiàn)象。

tips:搭建搜索UI又幾種方式:1)搜索框直接創(chuàng)建在導(dǎo)航欄 2)搜索欄創(chuàng)建在視圖頂部 3)自定義。根據(jù)你的需求用代碼~

(一)這里是第一種方式(搜索框直接創(chuàng)建在導(dǎo)航欄):

GMSAutocompleteViewController *acController = [[GMSAutocompleteViewController alloc] init];
 acController.delegate = self;
 [self presentViewController:acController animated:YES completion:nil];

tips:這里就可以直接往搜索框編輯文字,API會(huì)直接給你返回搜索結(jié)果集合

(二)調(diào)用API代理方法:

// Handle the user's selection. 這是用戶選擇搜索中的某個(gè)地址后返回的結(jié)果回調(diào)方法
- (void)viewController:(GMSAutocompleteViewController *)viewController
didAutocompleteWithPlace:(GMSPlace *)place {
  
 [self dismissViewControllerAnimated:YES completion:nil];
 [self.marker.map clear];
 self.marker.map = nil;
 // 通過(guò)location 或得到當(dāng)前位置的經(jīng)緯度
 GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:place.coordinate.latitude longitude:place.coordinate.longitude zoom:Level];
 CLLocationCoordinate2D position2D = CLLocationCoordinate2DMake(place.coordinate.latitude,place.coordinate.longitude);
 self.marker = [GMSMarker markerWithPosition:position2D];
 self.mapView.camera = camera;
 self.marker.map = self.mapView;
  
 self.locationLabel.text = place.name;
 self.locationDetailLabel.text = place.formattedAddress;
  
}

tips:這個(gè)代理方法實(shí)現(xiàn)的是,當(dāng)用戶在搜索集中選擇了在某一個(gè)結(jié)果返回地圖,并定位添加大頭針。

自動(dòng)填充失敗的回調(diào):

- (void)viewController:(GMSAutocompleteViewController *)viewController
didFailAutocompleteWithError:(NSError *)error {
 [self dismissViewControllerAnimated:YES completion:nil];
 // TODO: handle the error.
 DLog(@"Error: %@", [error description]);
}

tips:自動(dòng)填充失敗后你可以在這里做一些事,默認(rèn)是不管的。

補(bǔ)充:搜索欄的外觀是可以自定義的,你可以設(shè)置成跟自己的app一樣的風(fēng)格~具體請(qǐng)看設(shè)置 UI 控件樣式屬性

到這里,搜索功能就算完成了。

相關(guān)文章

  • iOS中關(guān)于Swift UICollectionView橫向分頁(yè)的問(wèn)題

    iOS中關(guān)于Swift UICollectionView橫向分頁(yè)的問(wèn)題

    這篇文章通過(guò)圖文并茂的形式給大家介紹UICollectionView橫向分頁(yè)的問(wèn)題,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧
    2017-05-05
  • iOS9開(kāi)放的新API--Spotlight使用指南

    iOS9開(kāi)放的新API--Spotlight使用指南

    作為蘋果iOS9的重要特性之一,Spotlight搜索如今重新回到主界面最左側(cè)(同樣支持主界面下滑呼出),通過(guò)API的支持,還帶來(lái)了全新的Universal Search通用搜索功能,除了網(wǎng)絡(luò)以及系統(tǒng)本身內(nèi)容之外,還能直接搜索第三方應(yīng)用內(nèi)的相關(guān)內(nèi)容。下面我們就來(lái)詳細(xì)研究下Spotlight
    2015-11-11
  • 解決Alamofire庫(kù)在iOS7下設(shè)置Head無(wú)效的問(wèn)題

    解決Alamofire庫(kù)在iOS7下設(shè)置Head無(wú)效的問(wèn)題

    本文主要介紹Alamofire庫(kù)在iOS下設(shè)置Head,這里通過(guò)代碼實(shí)例解決不同版本的IOS系統(tǒng)出現(xiàn)的問(wèn)題,有需要的小伙伴可以參考下
    2016-07-07
  • iOS自定義控件開(kāi)發(fā)梳理總結(jié)

    iOS自定義控件開(kāi)發(fā)梳理總結(jié)

    這篇文章主要介紹了iOS自定義控件開(kāi)發(fā)梳理總結(jié),自定義控件能讓我們完全控制視圖的展示內(nèi)容以及交互操作。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2016-11-11
  • iOS支付寶、微信、銀聯(lián)支付集成封裝調(diào)用(下)

    iOS支付寶、微信、銀聯(lián)支付集成封裝調(diào)用(下)

    本篇文章通過(guò)代碼實(shí)例給大家講述了iOS支付寶、微信、銀聯(lián)支付集成封裝調(diào)用,對(duì)此有需要的朋友可以測(cè)試參考下。
    2018-04-04
  • 淺談關(guān)于如何檢測(cè)iOS14本地網(wǎng)絡(luò)權(quán)限的一些思路

    淺談關(guān)于如何檢測(cè)iOS14本地網(wǎng)絡(luò)權(quán)限的一些思路

    這篇文章主要介紹了淺談關(guān)于如何檢測(cè)iOS14本地網(wǎng)絡(luò)權(quán)限的一些思路,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • IOS  Swift3 四種單例模式詳解及實(shí)例

    IOS Swift3 四種單例模式詳解及實(shí)例

    這篇文章主要介紹了IOS Swift3 四種單例模式詳解及實(shí)例的相關(guān)資料,這里對(duì)四種單例模式進(jìn)行了實(shí)例介紹 ,需要的朋友可以參考下
    2016-12-12
  • 2016最新CocoaPods安裝和錯(cuò)誤解決方案

    2016最新CocoaPods安裝和錯(cuò)誤解決方案

    CocoaPods是一個(gè)負(fù)責(zé)管理iOS項(xiàng)目中第三方開(kāi)源庫(kù)的工具,開(kāi)發(fā)iOS項(xiàng)目不可避免地要使用第三方開(kāi)源庫(kù)。接下來(lái)通過(guò)本文給大家介紹2016最新CocoaPods安裝和錯(cuò)誤解決方案,需要的的朋友參考下吧
    2016-11-11
  • 代碼詳解iOS視頻直播彈幕功能

    代碼詳解iOS視頻直播彈幕功能

    本篇文章通過(guò)原理分析和代碼實(shí)例講述了實(shí)現(xiàn)iOS視頻直播彈幕功能的方法,需要的朋友參考學(xué)習(xí)下吧。
    2017-12-12
  • IOS安裝包比Android容量大的原因

    IOS安裝包比Android容量大的原因

    這篇文章主要介紹了為什么IOS安裝包比Android容量大的原因,如果你是一個(gè)IOS或者安卓開(kāi)發(fā)者,學(xué)習(xí)下相關(guān)知識(shí)吧。
    2018-02-02

最新評(píng)論

那曲县| 阳春市| 雷州市| 灌南县| 蓝山县| 格尔木市| 横峰县| 黄冈市| 遂平县| 南部县| 汕头市| 桃江县| 麻城市| 藁城市| 青川县| 韶关市| 隆林| 大悟县| 榆社县| 金堂县| 舒城县| 布尔津县| 嵩明县| 农安县| 忻城县| 平顺县| 宣恩县| 朝阳市| 芦山县| 云林县| 吴桥县| 博爱县| 思茅市| 鹿泉市| 嘉祥县| 海丰县| 弋阳县| 五华县| 马尔康县| 泰宁县| 龙口市|