(iOS)教你如何使用定位服務

一.定位功能

1.ios7中的定位

1.1 導入 CoreLocation框架

1.2 創(chuàng)建 CLLocationManager對象

注意:要用強指針指向這個對象,一般采用懶加載來創(chuàng)建

privatelazyvarmgr :CLLocationManager=CLLocationManager()

1.3 設置代理,實現(xiàn)代理方法

1.4 開始定位

mgr.startUpdatingLocation()

1.5 優(yōu)點:不需要設置用戶的授權

在info.plist加上一個key? Privacy - Location Usage Description 寫在value上的文字,可以顯示在提示權限的文本框內

2.ios8(之后)的定位

2.1 請求定位步驟

2.11 導入CoreLocation框架

2.12 懶加載CLLocationManager對象

2.13 請求授權 (1) whenInUse (2) always

2.14 注意:必須把授權對應的key值 添加到info.plist文件中

2.15 設置代理,實現(xiàn)代理方法

2.16 開始定位

2.2 定位屬性的應用

2.21 精確度的使用

desiredAccuracy精確度越高,越耗電

屬性接收double類型的值,不過最好傳系統(tǒng)給定好的值

kCLLocationAccuracyBestForNavigation: 導航精確度(最精確)

kCLLocationAccuracyBest: 最好精確度(默認)

kCLLocationAccuracyNearestTenMeters: 10米的誤差

kCLLocationAccuracyHundredMeters: 100米的誤差

kCLLocationAccuracyKilometer: 千米誤差

kCLLocationAccuracyThreeKilometers: 三千米的誤差

mgr.desiredAccuracy = kCLLocationAccuracyBestForNavigation

2.22 移動一段距離,再次重新定位

設置用于移動多少距離,重新進行定位

mgr.distanceFilter =100

2.3 位置信息的獲取

2.31 發(fā)送完請求定位,怎么獲取位置信息?

在代理方法的閉包中,有一個數組,返回了很多信息在里面

2.32 我們常用的信息就是經緯度

二.計算兩個經緯度的距離

1.獲取當前位置信息

1.1 導入框架

1.2 懶加載管理者對象

1.3 請求授權

1.4 添加key值

1.5 設置代理,實現(xiàn)代理方法

1.6 開始定位

2.獲取另一個位置的經緯度

.

3.計算兩個位置的距離distanceFromLocation

三.簡易指南針的制作

1.實現(xiàn)思路

監(jiān)聽手機頭方向的改變,在手機屏幕上放一張圖片,始終指向北(根據手機方向的改變旋轉)

2.界面搭建

拖一個UIImageView放在屏幕中央,里面放一張圖片

3.監(jiān)聽手機頭方向的改變

3.1 怎么監(jiān)聽?

通過發(fā)送請求(定位服務),獲取手機頭的方向進行監(jiān)聽

3.2 具體實現(xiàn)

3.21 導入CoreLocation框架

3.22 懶加載CLLocationManager對象

3.23 請求授權 (1) whenInUse (2) always

3.24 注意:必須把授權對應的key值 添加到info.plist文件中

3.25 設置代理,實現(xiàn)代理方法

3.26 請求手機頭方向

3.27 獲取真北方向

3.28 將真北方向轉換為弧度

3.29 讓圖片根據弧度進行旋轉(注意:圖片旋轉的弧度要取反 ,? 要和屏幕旋轉方向相反才能保持一直指向一個方向)

4.對指南針優(yōu)化

4.1 真實的指南針指向一個位置,會來回擺動兩下才固定位置

代碼實現(xiàn)的指南針沒有這個效果

4.2 如何實現(xiàn)這個效果?

可以通過一個動畫來實現(xiàn)

// Damping : 阻力系數 (0~1.0)? ? ? initialSpringVelocity:回彈速度UIView.animateWithDuration(0.5, delay:0.0, usingSpringWithDamping:0.8, initialSpringVelocity:5.0, options: [], animations: {? ? ? ? self.imageView.transform = transform? ? ? ? }, completion: nil)

四.區(qū)域監(jiān)聽

1.需求,當進入某指向區(qū)域,提醒用戶進入該區(qū)域,離開該區(qū)域也對用戶進行提醒

.

2.實現(xiàn)方案步驟

2.1 懶加載 CLLocationManager對象

2.2 請求授權(注意:必須使用alyays授權方式) ,配置info文件

2.3 設置代理

2.4 創(chuàng)建監(jiān)聽區(qū)域

2.5 實現(xiàn)代理方法 并 開始監(jiān)聽

3.注意點

3.1 當之前添加過監(jiān)聽區(qū)域時,再次添加新的監(jiān)聽區(qū)域,還會對之前的區(qū)域進行監(jiān)聽

3.2 不想監(jiān)聽之前的區(qū)域,必須通過代碼移除之前的區(qū)域

五.地理編碼&反地理編碼

需求:輸入地理名稱,地理編碼獲得該位置的經緯度.? 輸入經緯度,輸出對應位置的地理名稱

1.界面搭建

1.1? 整個界面放在屏幕的中心,怎么實現(xiàn)?

1.11 可以用view包裝

優(yōu)缺點:要做大量的約束? , 但可以應用于任何版本

1.12 ios9之后可以用UIStackView來包裝

優(yōu)缺點:布局簡便? 只能適用于ios9(之后)

2.地理編碼

2.1 拿到用戶輸入的地理名稱 (導入框架CoreLocation)

2.2 地理編碼

2.21 創(chuàng)建 CLGeocoder對象

2.22 對地理名稱進行地理編碼

geocoder.geocodeAddressString(address) { (<#[CLPlacemark]?#>,<#NSError?#>) in<#code#>}

2.23 對閉包中的CLPlacemark數據就行解析(遍歷)

一個地理名稱可能對應多個地方,所以編碼后的到的結果是一個數組

2.24 獲取數組中元素的地理位置(經緯度)

2.25 將經緯度顯示到界面

3.反地理編碼

3.1 拿到用戶輸入的經緯度

3.2 對經緯度進行反地理編碼

3.21 創(chuàng)建 CLGeocoder對象

3.22 對經緯度進行反地理編碼

geocoder.reverseGeocodeLocation(location) { (<#[CLPlacemark]?#>,<#NSError?#>) in<#code#>}

3.23 對閉包中的CLPlacemark數據就行解析(遍歷)

一個經緯度可能對應多個位置(蘋果這么設計的)? 所以編碼后返回一個數組

一個位置包含多個信息(省/市/街道/國家/經緯度/)? 編碼后的結果是字典數組

3.24 取出數組中的一個位置(字典),再獲取位置信息(取出字典的元素)

3.25 把獲取到的地理名稱顯示到界面

地理編碼&反地理編碼源代碼

classViewController:UIViewController{// MARK:- 控件屬性@IBOutletweakvaraddressTextView:UITextView!

@IBOutletweakvarlatitudeTextField:UITextField!

@IBOutletweakvarlongitudeTextField:UITextField!

// MARK:- 懶加載屬性private lazyvargeocoder :CLGeocoder=CLGeocoder()}// MARK:- 地理編碼extensionViewController{@IBActionfuncgeocode(){// 1.獲取用戶輸入的地址名稱guardletaddress = addressTextView.textelse{return}// 2.對地理名稱進行地理編碼geocoder.geocodeAddressString(address) { (placemarks : [CLPlacemark]?, error :NSError?)in// 1.錯誤校驗iferror !=nil{print(error)return}// 2.對結果進行校驗guardletplacemarks = placemarkselse{return}// 3.遍歷所有的結果forplaceinplacemarks {print(place.name)// 獲取地理位置guardletlocation = place.locationelse{continue}// 獲取經緯度letlatitude = location.coordinate.latitudeletlongitude = location.coordinate.longitude// 將經緯度顯示textField中self.latitudeTextField.text ="\(latitude)"self.longitudeTextField.text ="\(longitude)"}? ? }}}// MARK:- 反地理編碼extensionViewController{@IBActionfuncreverseGeocode(){// 1.獲取用戶輸入的經緯度guardletlatitude = latitudeTextField.text,letlongitude = longitudeTextField.textelse{return}// 2.將經緯度轉成CLLocation對象guardletlatitudeD =Double(latitude),letlongitudeD =Double(longitude)else{return}letlocation =CLLocation(latitude: latitudeD, longitude: longitudeD)// 3.反地理編碼geocoder.reverseGeocodeLocation(location) { (placemarks : [CLPlacemark]?, error :NSError?)in// 1.錯誤校驗iferror !=nil{print(error)return}// 2.對結果進行校驗guardletplacemarks = placemarkselse{return}// 3.遍歷結果forplaceinplacemarks {? ? ? ? ? ? guardletaddressDict = place.addressDictionaryelse{continue}? ? ? ? ? ? guardletaddressArray = addressDict["FormattedAddressLines"]as? [String]else{continue}? ? ? ? ? ? guardletaddress = addressArray.lastelse{continue}self.addressTextView.text = address? ? ? ? }? ? }}}

六.把定位封裝為工具類

1.將工具類設計成單例對象

2.封裝請求方法,在方法中傳入閉包

2.1 使用屬性將閉包保存起來. (因為在代理方法才能拿到位置信息)

2.2 請求用戶位置(1.懶加載管理者對象,并在對象中直接設置請求授權和代理)

3.在代理方法中獲得用戶位置信息,并賦值給閉包屬性

4.停止請求用戶的位置

mgr.stopUpdatingLocation()

5.當第一次發(fā)送請求位置信息,會返回多次位置信息,怎么解決這個問題?

用戶只需要定義一個Bool屬性,對屬性進行判斷,為true就接收返回的位置信息

七.使用第三方框架請求位置信息

去github搜索LocationManager 找到框架去使用

一般用oc版的,swift也能用

文/尕小天(簡書作者)

原文鏈接:http://www.itdecent.cn/p/20dbde944f2a

著作權歸作者所有,轉載請聯(lián)系作者獲得授權,并標注“簡書作者”。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容