??關于地圖定位,我們需要知道,地圖信息是放在 MapKit 當中的, 定位是放在 CoreLocation 里面的。在以前的版本中你需要在設置中添加這些你需要用到的 framework 框架,現(xiàn)在最新版本似乎是不需要,可以直接導入了。下圖是手動添加的視圖:

添加framework.png
??在BLDemo3中的 第五個視圖控制器類中 BLFiveViewController 導入框架:
#import <UIKit/UIKit.h>
#import <BLBaseViewController.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
@interface BLFiveViewController:BLBaseViewController<CLLocationManagerDelegate,MKMapViewDelegate>
{
MKMapView *_mapView;
UILabel *_locationLabel;
NSMutableArray *_annotations;
}
@property(nonatomic, strong) CLLocationManager *locationManager;
@property(nonatomic, strong) CLLocation *currentLocation;
@property(nonatomic, strong) CLGeocoder *geocoder;
@end
??為了展示地圖,首先需要生成一個地圖的對象在上面:
_mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 64, width, height - 64 - 49 -50)];
// _mapView.showsUserLocation = YES; 一旦開啟,在地圖界面右上角狀態(tài)欄會有一個黑色定位的小圖標,顯示手機當前的定位。一般不建議打開,耗電。
_mapView.delegate = self;
[self.view addSubview:_mapView];
??地圖添加到 view 之上后, 需要設置一個坐標位置點(設置好地點的經(jīng)緯度之后,它將顯示在地圖的中心點位置),設置縮放比例(兩個參數(shù),分別代表緯度和經(jīng)度的縮放比例),然后上面兩個數(shù)據(jù)成為設置區(qū)域方法的兩個參數(shù):
Cllocationcoordinate2D coordinate = {31.19316, 121.34221};
MKCoordinateSpan span = {0.05, 0.05};
MKCoordinateRegion region = {coordinate, span};
[_mapView setRegion:region];
??然后,需要在視圖的 navigationBar 上添加幾個控件,這幾個控件是 UIBarButtonItem:
UIBarButtonItem *locationButton = [[UIBarButtonItem alloc] initWithTitle:@"定位"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(locationButtonClicked:)];
self.navigationItem.leftBarButtonItem = locationButton;
UIBarButtonItem *reverseButton = [[UIBarButtonItem alloc] initWithTitle:@"解析"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(reverseButtonClicked:)];
UIBarButtonItem *flagButton = [[UIBarButtonItem alloc] initWithTitle:@"標記"
style:UIBarButtonItemStyleBordered
target:self
action:@selector(flagButtonClicked:)];
self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:reverseButton, flagButton, nil]; // 在 iOS 5 之前只能添加一個按鈕
??定位的方法如下:
- (void)locationButtonClicked:(id)sender
{
if (self.locationManager == nil) {
self.locationManager = [[CLLocationManger alloc] init];
self.locationManager.delegate = self;
if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { // 如果系統(tǒng)設備 >= 8.0
[self.locationManager requestWhenInUseAuthorization]; // authorization 授權
} else {
[self.locationManager startUpdatingLocation];
}
??里面有關于 ios8 之后才有的用戶定位請求授權功能,如下圖所示:

定位請求.jpg
??這個方法也是需要代理回調(diào)的,代碼如下:
#pragma mark - CLLocationManagerDelegate methods
- (void) locationManager:(CLLocationManager *)manager didChangerAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusNotDetermined) {
NSLog(@"等待用戶授權");
} else if (status == kCLAuthorizationStatusAuthorizedAlways || // 點選了允許之后就是這兩個狀態(tài)
status == kCLAuthorizationStatusAutorizedWhenInUse) {
[self.locationManager startUpdatingLocation];
} else {
NSLog(@"授權失敗");
}
}
??在開發(fā)中還有一個坑,當你請求用戶授權,寫入如上代碼還是不夠的,還需要到項目中,點擊targets,選擇項目,在info 設置中 選擇設置 NSlocationWhenInUseUsageDescription ,內(nèi)容value 設置為 “需要定位”,走完這個流程才能請求授權,才能定位:

定位用戶授權的工程設置.jpg
??定位成功或者失敗多次之后,需要停止定位 (stopUpdatingLocation),也在代理中含有方法,觀察里面的一些方法代碼:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
[self.locationManager stopUpdatingLocation];
NSLog(@"%@", error.description);
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[self.locationManager stopUpdatingLocation];
self.currentLocation = newLocation;
CLLocationDistance distance = [newLocation distanceFromLocation:oldLocation];
_locationLabel.text = [NSString stringWithFormat:@"%f, %f",newLocation.coordinate.latitude, newLocation.coordinate.longitude];
}