一.定位功能
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)系作者獲得授權,并標注“簡書作者”。