(iOS)會(huì)使用定位功能嗎? 不會(huì)就來(lái)看看吧

一.定位功能

1.ios7中的定位

1.1 導(dǎo)入 CoreLocation框架

1.2 創(chuàng)建 CLLocationManager對(duì)象
注意:要用強(qiáng)指針指向這個(gè)對(duì)象,一般采用懶加載來(lái)創(chuàng)建

 private lazy var mgr : CLLocationManager = CLLocationManager()

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

1.4 開始定位

 mgr.startUpdatingLocation()

1.5 優(yōu)點(diǎn):不需要設(shè)置用戶的授權(quán)

在info.plist加上一個(gè)key Privacy - Location Usage Description 寫在value上的文字,可以顯示在提示權(quán)限的文本框內(nèi)

2.ios8(之后)的定位

2.1 請(qǐng)求定位步驟

2.11 導(dǎo)入CoreLocation框架
2.12 懶加載CLLocationManager對(duì)象
2.13 請(qǐng)求授權(quán) (1) whenInUse (2) always
2.14 注意:必須把授權(quán)對(duì)應(yīng)的key值 添加到info.plist文件中
2.15 設(shè)置代理,實(shí)現(xiàn)代理方法
2.16 開始定位

2.2 定位屬性的應(yīng)用

2.21 精確度的使用

desiredAccuracy精確度越高,越耗電
屬性接收double類型的值,不過最好傳系統(tǒng)給定好的值
kCLLocationAccuracyBestForNavigation: 導(dǎo)航精確度(最精確)
kCLLocationAccuracyBest: 最好精確度(默認(rèn))
kCLLocationAccuracyNearestTenMeters: 10米的誤差
kCLLocationAccuracyHundredMeters: 100米的誤差
kCLLocationAccuracyKilometer: 千米誤差
kCLLocationAccuracyThreeKilometers: 三千米的誤差

    mgr.desiredAccuracy = kCLLocationAccuracyBestForNavigation

2.22 移動(dòng)一段距離,再次重新定位
設(shè)置用于移動(dòng)多少距離,重新進(jìn)行定位

         mgr.distanceFilter = 100

2.3 位置信息的獲取

2.31 發(fā)送完請(qǐng)求定位,怎么獲取位置信息?
在代理方法的閉包中,有一個(gè)數(shù)組,返回了很多信息在里面

2.32 我們常用的信息就是經(jīng)緯度

二.計(jì)算兩個(gè)經(jīng)緯度的距離

1.獲取當(dāng)前位置信息

1.1 導(dǎo)入框架
1.2 懶加載管理者對(duì)象
1.3 請(qǐng)求授權(quán)
1.4 添加key值
1.5 設(shè)置代理,實(shí)現(xiàn)代理方法
1.6 開始定位

2.獲取另一個(gè)位置的經(jīng)緯度

.

3.計(jì)算兩個(gè)位置的距離 distanceFromLocation

三.簡(jiǎn)易指南針的制作

1.實(shí)現(xiàn)思路

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

2.界面搭建

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

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

3.1 怎么監(jiān)聽?
通過發(fā)送請(qǐng)求(定位服務(wù)),獲取手機(jī)頭的方向進(jìn)行監(jiān)聽

3.2 具體實(shí)現(xiàn)

3.21 導(dǎo)入CoreLocation框架
3.22 懶加載CLLocationManager對(duì)象

      3.23 請(qǐng)求授權(quán) (1) whenInUse (2) always
      3.24 注意:必須把授權(quán)對(duì)應(yīng)的key值 添加到info.plist文件中
      3.25 設(shè)置代理,實(shí)現(xiàn)代理方法
      3.26 請(qǐng)求手機(jī)頭方向
      3.27 獲取真北方向
      3.28 將真北方向轉(zhuǎn)換為弧度
      3.29 讓圖片根據(jù)弧度進(jìn)行旋轉(zhuǎn)(注意:圖片旋轉(zhuǎn)的弧度要取反 ,  要和屏幕旋轉(zhuǎn)方向相反才能保持一直指向一個(gè)方向)

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

4.1 真實(shí)的指南針指向一個(gè)位置,會(huì)來(lái)回?cái)[動(dòng)兩下才固定位置
代碼實(shí)現(xiàn)的指南針沒有這個(gè)效果

4.2 如何實(shí)現(xiàn)這個(gè)效果?
可以通過一個(gè)動(dòng)畫來(lái)實(shí)現(xiàn)

    // Damping : 阻力系數(shù) (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.需求,當(dāng)進(jìn)入某指向區(qū)域,提醒用戶進(jìn)入該區(qū)域,離開該區(qū)域也對(duì)用戶進(jìn)行提醒

.

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

2.1 懶加載 CLLocationManager對(duì)象
2.2 請(qǐng)求授權(quán)(注意:必須使用alyays授權(quán)方式) ,配置info文件
2.3 設(shè)置代理
2.4 創(chuàng)建監(jiān)聽區(qū)域
2.5 實(shí)現(xiàn)代理方法 并 開始監(jiān)聽

3.注意點(diǎn)

3.1 當(dāng)之前添加過監(jiān)聽區(qū)域時(shí),再次添加新的監(jiān)聽區(qū)域,還會(huì)對(duì)之前的區(qū)域進(jìn)行監(jiān)聽

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

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

需求:輸入地理名稱,地理編碼獲得該位置的經(jīng)緯度. 輸入經(jīng)緯度,輸出對(duì)應(yīng)位置的地理名稱

1.界面搭建

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

1.11 可以用view包裝
優(yōu)缺點(diǎn):要做大量的約束 , 但可以應(yīng)用于任何版本

1.12 ios9之后可以用UIStackView來(lái)包裝
優(yōu)缺點(diǎn):布局簡(jiǎn)便 只能適用于ios9(之后)

2.地理編碼

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

2.2 地理編碼

2.21 創(chuàng)建 CLGeocoder對(duì)象
2.22 對(duì)地理名稱進(jìn)行地理編碼

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

2.23 對(duì)閉包中的CLPlacemark數(shù)據(jù)就行解析(遍歷)
一個(gè)地理名稱可能對(duì)應(yīng)多個(gè)地方,所以編碼后的到的結(jié)果是一個(gè)數(shù)組

2.24 獲取數(shù)組中元素的地理位置(經(jīng)緯度)

2.25 將經(jīng)緯度顯示到界面

3.反地理編碼

3.1 拿到用戶輸入的經(jīng)緯度

3.2 對(duì)經(jīng)緯度進(jìn)行反地理編碼

3.21 創(chuàng)建 CLGeocoder對(duì)象
3.22 對(duì)經(jīng)緯度進(jìn)行反地理編碼

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

3.23 對(duì)閉包中的CLPlacemark數(shù)據(jù)就行解析(遍歷)
一個(gè)經(jīng)緯度可能對(duì)應(yīng)多個(gè)位置(蘋果這么設(shè)計(jì)的) 所以編碼后返回一個(gè)數(shù)組
一個(gè)位置包含多個(gè)信息(省/市/街道/國(guó)家/經(jīng)緯度/) 編碼后的結(jié)果是字典數(shù)組

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

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

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

class ViewController: UIViewController {

// MARK:- 控件屬性
@IBOutlet weak var addressTextView: UITextView!
@IBOutlet weak var latitudeTextField: UITextField!
@IBOutlet weak var longitudeTextField: UITextField!
// MARK:- 懶加載屬性
private lazy var geocoder : CLGeocoder = CLGeocoder()
}

// MARK:- 地理編碼
extension ViewController {
@IBAction func geocode() {

    // 1.獲取用戶輸入的地址名稱
    guard let address = addressTextView.text else {
        return
    }
    // 2.對(duì)地理名稱進(jìn)行地理編碼
    geocoder.geocodeAddressString(address) { (placemarks : [CLPlacemark]?, error : NSError?) in
        // 1.錯(cuò)誤校驗(yàn)
        if error != nil {
            print(error)
            return
        }
        // 2.對(duì)結(jié)果進(jìn)行校驗(yàn)
        guard let placemarks = placemarks else {
            return
        }
        // 3.遍歷所有的結(jié)果
        for place in placemarks {
            print(place.name)

            // 獲取地理位置
            guard let location = place.location else {
                continue
            }

            // 獲取經(jīng)緯度
            let latitude = location.coordinate.latitude
            let longitude = location.coordinate.longitude

            // 將經(jīng)緯度顯示textField中
            self.latitudeTextField.text = "\(latitude)"
            self.longitudeTextField.text = "\(longitude)"
        }
    }
}
}

// MARK:- 反地理編碼
extension ViewController {
@IBAction func reverseGeocode() {
    // 1.獲取用戶輸入的經(jīng)緯度
    guard let latitude = latitudeTextField.text, let longitude = longitudeTextField.text else {
        return
    }

    // 2.將經(jīng)緯度轉(zhuǎn)成CLLocation對(duì)象
    guard let latitudeD = Double(latitude), let longitudeD = Double(longitude) else {
        return
    }
    let location = CLLocation(latitude: latitudeD, longitude: longitudeD)

    // 3.反地理編碼
    geocoder.reverseGeocodeLocation(location) { (placemarks : [CLPlacemark]?, error : NSError?) in
        // 1.錯(cuò)誤校驗(yàn)
        if error != nil {
            print(error)
            return
        }

        // 2.對(duì)結(jié)果進(jìn)行校驗(yàn)
        guard let placemarks = placemarks else {
            return
        }
        // 3.遍歷結(jié)果
        for place in placemarks {
            guard let addressDict = place.addressDictionary else {
                continue
            }

            guard let addressArray = addressDict["FormattedAddressLines"] as? [String] else {
                continue
            }

            guard let address = addressArray.last else {
                continue
            }

            self.addressTextView.text = address
        }
    }
}
}

六.把定位封裝為工具類

1.將工具類設(shè)計(jì)成單例對(duì)象

2.封裝請(qǐng)求方法,在方法中傳入閉包

2.1 使用屬性將閉包保存起來(lái). (因?yàn)樵诖矸椒ú拍苣玫轿恢眯畔?
2.2 請(qǐng)求用戶位置(1.懶加載管理者對(duì)象,并在對(duì)象中直接設(shè)置請(qǐng)求授權(quán)和代理)

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

4.停止請(qǐng)求用戶的位置

 mgr.stopUpdatingLocation()

5.當(dāng)?shù)谝淮伟l(fā)送請(qǐng)求位置信息,會(huì)返回多次位置信息,怎么解決這個(gè)問題?
用戶只需要定義一個(gè)Bool屬性,對(duì)屬性進(jìn)行判斷,為true就接收返回的位置信息

七.使用第三方框架請(qǐng)求位置信息

去github搜索LocationManager 找到框架去使用
一般用oc版的,swift也能用

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容