新聞中心
9.3 方向監(jiān)測(cè)
擁有GPS硬件的設(shè)備可以生成設(shè)備的當(dāng)前方向(course屬性)和速度信息。iPhone設(shè)備攜帶的定位管理器可以返回一個(gè)已經(jīng)計(jì)算好的course值,通過(guò)這個(gè)值我們可以獲得當(dāng)前前進(jìn)的方向,course值是0~360之間的浮點(diǎn)數(shù),0°值表示正北方向,90°值表示正東方向,180°值表示正南方向,270°值表示正西方向,程序可以通過(guò)course值來(lái)檢測(cè)用戶位置的移動(dòng)方向。除此之外,還可以通過(guò)磁力計(jì)來(lái)獲取設(shè)備的真實(shí)方向。
提示:
地球是一個(gè)大磁場(chǎng),磁力計(jì)的北極將會(huì)永遠(yuǎn)真實(shí)地指向北方。
iOS系統(tǒng)通過(guò)heading屬性來(lái)獲取設(shè)備的真實(shí)方向。需要指出的是,并不是所有的iOS設(shè)備都支持heading屬性,從iPhone 3gs開(kāi)始引入了磁力計(jì),因此程序在獲取方向之前需要先測(cè)試該設(shè)備是否支持heading。如果定位管理器支持heading屬性,那么CLLocationManager的headingAvailable屬性將會(huì)返回“YES”。使用CLLocationManager獲取設(shè)備方向與獲取移動(dòng)距離的步驟基本相似,只是此時(shí)不是檢測(cè)位置移動(dòng),而是檢測(cè)方向改變。
使用CLLocationManager獲取設(shè)備方向的步驟如下。
創(chuàng)建CLLocationManager對(duì)象,該對(duì)象負(fù)責(zé)獲取定位相關(guān)信息。并為該對(duì)象設(shè)置一些必要的屬性。
為CLLocationManager指定delegate屬性,該屬性值必須是一個(gè)實(shí)現(xiàn)CLLocationManagerDelegate協(xié)議的對(duì)象。實(shí)現(xiàn)CLLocationManagerDelegate協(xié)議時(shí)可根據(jù)需要實(shí)現(xiàn)協(xié)議中特定的方法。
調(diào)用CLLocationManager的startUpdatingHeading方法獲取方向信息。獲取方向結(jié)束時(shí),可調(diào)用stopUpdatingHeading方法結(jié)束獲取方向信息。
當(dāng)設(shè)備的方向改變時(shí),iOS系統(tǒng)將會(huì)自動(dòng)激發(fā)CLLocationManager的delegate對(duì)象的locationManager:didUpdateHeading:方法,而程序可通過(guò)重寫(xiě)該方法來(lái)獲取設(shè)備方向。
iOS允許為檢測(cè)方向改變?cè)O(shè)置如下屬性。
CLLocationDegrees headingFilter:設(shè)置只有當(dāng)設(shè)備方向的改變值超過(guò)該屬性值時(shí)才激發(fā)delegate的方法。
CLDeviceOrientation headingOrientation:設(shè)置設(shè)備當(dāng)前方向。
監(jiān)聽(tīng)方向時(shí)返回的是一個(gè)CLHeading對(duì)象,該對(duì)象包含如下屬性。
magneticHeading:該屬性返回設(shè)備與磁北的相對(duì)方向。
trueHeading:該屬性返回設(shè)備與真北的相對(duì)方向。 提示:真北始終指向地理北極點(diǎn);磁北則對(duì)應(yīng)于隨時(shí)間變化的地球磁場(chǎng)北極。iOS系統(tǒng)使用一個(gè)計(jì)算后的偏移量(稱為偏差)來(lái)確定這兩者之間的差異。
headingAccuracy:該屬性返回方向值的誤差范圍。
timestamp:該屬性返回方向值的生成時(shí)間。
x:獲取該設(shè)備在X方向上監(jiān)聽(tīng)得到的原始磁力值,該磁力值的強(qiáng)度單位是微特斯拉。
y:獲取該設(shè)備在Y方向上監(jiān)聽(tīng)得到的原始磁力值,該磁力值的強(qiáng)度單位是微特斯拉。
z:獲取該設(shè)備在Z方向上監(jiān)聽(tīng)得到的原始磁力值,該磁力值的強(qiáng)度單位是微特斯拉。
在啟用該功能的iOS設(shè)備上,即使用戶在Settings應(yīng)用中關(guān)閉了定位更新,磁向更新仍然可以使用。此外,使用heading服務(wù)的應(yīng)用不會(huì)提示用戶授權(quán)問(wèn)題,因此磁向信息不會(huì)泄露用戶的隱私,應(yīng)用程序可以隨便使用它。
需要說(shuō)明的是,trueHeading屬性需要與位置探測(cè)功能一起使用,iOS系統(tǒng)需要設(shè)備的位置來(lái)計(jì)算確定真北所需要的偏差。偏差隨地理位置的變化而變化,比如北京的偏差不同于東京的偏差,也不同于新加坡和馬來(lái)西亞的偏差等。有一些地方根本不能使用磁力計(jì)進(jìn)行讀數(shù)。
除此之外,在某些特殊位置例如有強(qiáng)磁、強(qiáng)電干擾的地方,磁力計(jì)可能無(wú)法使用。
實(shí)例:指南針此實(shí)例將會(huì)示范如何使用磁力計(jì)來(lái)獲取設(shè)備方向,然后根據(jù)設(shè)備方向來(lái)創(chuàng)建一個(gè)指南針應(yīng)用。新建一個(gè)Single View Application,無(wú)須修改界面設(shè)計(jì)文件,直接在應(yīng)用的視圖控制器類的實(shí)現(xiàn)部分創(chuàng)建界面,并讓?xiě)?yīng)用中顯示方向的圖片隨著設(shè)備方向自動(dòng)旋轉(zhuǎn)即可。
下面是該應(yīng)用的視圖控制器類的實(shí)現(xiàn)部分代碼。
程序清單:codes/09/9.3/Compass/Compass/FKViewController.m
@interface FKViewController (){ CALayer* znzLayer; } @property (nonatomic , strong)CLLocationManager *locationManager; @end @implementation FKViewController - (void)viewDidLoad { [super viewDidLoad]; // 如果磁力計(jì)可用,則開(kāi)始監(jiān)聽(tīng)方向改變 if([CLLocationManager headingAvailable]) { // 創(chuàng)建顯示方向的指南針圖片Layer znzLayer = [[CALayer alloc] init]; NSInteger screenHeight = [UIScreen mainScreen].bounds.size.height; NSInteger y = (screenHeight - 320) / 2; znzLayer.frame = CGRectMake(0 , y , 320, 320); // 設(shè)置znzLayer顯示的圖片 znzLayer.contents = (id)[[UIImage p_w_picpathNamed:@"znz.png"] CGImage]; // 將znzLayer添加到系統(tǒng)的UIView中 [self.view.layer addSublayer:znzLayer]; // 創(chuàng)建CLLocationManager對(duì)象 self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; [self.locationManager startUpdatingHeading]; } // 如果磁力計(jì)不可用,則使用UIAlertView顯示提示信息 else { // 使用警告框提醒用戶 [[[UIAlertView alloc] initWithTitle:@"提醒" message:@"您的設(shè)備不支持磁力計(jì)" delegate:self cancelButtonTitle:@"確定" otherButtonTitles: nil] show]; } } // 當(dāng)成功獲取設(shè)備的方向值后激發(fā)該方法 -(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { // 將設(shè)備的方向角度換算成弧度 CGFloat headings = -1.0f * M_PI * newHeading.magneticHeading / 180.0f; // 創(chuàng)建不斷改變CALayer的transform屬性的屬性動(dòng)畫(huà) CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"transform"]; CATransform3D fromValue = znzLayer.transform; // 設(shè)置動(dòng)畫(huà)開(kāi)始的屬性值 anim.fromValue = [NSValue valueWithCATransform3D: fromValue]; // 繞Z軸旋轉(zhuǎn)heading弧度的變換矩陣 CATransform3D toValue = CATransform3DMakeRotation(headings , 0 , 0 , 1); // 設(shè)置動(dòng)畫(huà)結(jié)束的屬性 anim.toValue = [NSValue valueWithCATransform3D: toValue]; anim.duration = 0.5; anim.removedOnCompletion = YES; // 設(shè)置動(dòng)畫(huà)結(jié)束后znzLayer的變換矩陣 znzLayer.transform = toValue; // 為znzLayer添加動(dòng)畫(huà) [znzLayer addAnimation:anim forKey:nil]; } -(BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager { return YES; } @end
上面程序中的前兩行粗體字代碼用于為CLLocationManager設(shè)置delegate屬性,接下來(lái)程序調(diào)用該對(duì)象的startUpdatingHeading方法開(kāi)始監(jiān)聽(tīng)設(shè)備的方向改變——當(dāng)設(shè)備的方向改變時(shí),系統(tǒng)會(huì)自動(dòng)激發(fā)CLLocationManager設(shè)置delegate的locationManager:didUpdateHeading:方法,程序的視圖控制器重寫(xiě)了該方法,并在該方法中獲取設(shè)備方向,然后將圖片“反轉(zhuǎn)”相應(yīng)的角度,從而讓圖片的北極總是指向真實(shí)的北極。
編譯、運(yùn)行該應(yīng)用(要在真機(jī)上測(cè)試該應(yīng)用,因?yàn)閕OS模擬器不支持磁力計(jì)),將可以看到如圖9.5所示的效果。

————本文節(jié)選自《瘋狂ios講義(下)》

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)頁(yè)題目:瘋狂ios講義之使用CoreLocation定位(3)-創(chuàng)新互聯(lián)
網(wǎng)頁(yè)路徑:http://fisionsoft.com.cn/article/dejdcg.html