关于地图定位,我们需要知道,地图信息是放在 MapKit 当中的, 定位是放在 CoreLocation 里面的。在以前的版本中你需要在设置中添加这些你需要用到的 framework 框架,现在最新版本似乎是不需要,可以直接导入了。下图是手动添加的视图:
在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; 一旦开启,在地图界面右上角状态栏会有一个黑色定位的小图标,显示手机当前的定位。一般不建议打开,耗电。
_mapView.delegate = self;
[self.view addSubview:_mapView];
地图添加到 view 之上后, 需要设置一个坐标位置点(设置好地点的经纬度之后,它将显示在地图的中心点位置),设置缩放比例(两个参数,分别代表纬度和经度的缩放比例),然后上面两个数据成为设置区域方法的两个参数:
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) { // 如果系统设备 >= 8.0
[self.locationManager requestWhenInUseAuthorization]; // authorization 授权
} else {
[self.locationManager startUpdatingLocation];
}
里面有关于 ios8 之后才有的用户定位请求授权功能,如下图所示:
这个方法也是需要代理回调的,代码如下:
#pragma mark - CLLocationManagerDelegate methods
- (void) locationManager:(CLLocationManager *)manager didChangerAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusNotDetermined) {
NSLog(@"等待用户授权");
} else if (status == kCLAuthorizationStatusAuthorizedAlways || // 点选了允许之后就是这两个状态
status == kCLAuthorizationStatusAutorizedWhenInUse) {
[self.locationManager startUpdatingLocation];
} else {
NSLog(@"授权失败");
}
}
在开发中还有一个坑,当你请求用户授权,写入如上代码还是不够的,还需要到项目中,点击targets,选择项目,在info 设置中 选择设置 NSlocationWhenInUseUsageDescription ,内容value 设置为 “需要定位”,走完这个流程才能请求授权,才能定位:
定位成功或者失败多次之后,需要停止定位 (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];
}