// 前台定位
// 1. 导入CoreLocation框架和对应的主头文件
#import
// 2. 创建CLLcationManager对象,并设置代理
_locationM = [[CLLocationManager alloc] init];
_locationM.delegate = self;
// 3. 调用CLLcationManager对象的startUpdatingLocation方法进行更新用户位置
[_locationM startUpdatingLocation];
// 4. 实现代理方法,接收位置参数
-(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray *)locations
#import
_locationM = [[CLLocationManager alloc] init];
_locationM.delegate = self;
[_locationM requestWhenInUseAuthorization];
[_locationM startUpdatingLocation];
-(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations
方法二:
监听权限状态改变
// 在状态授权状态时调用
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
/**
typedef NS_ENUM(int, CLAuthorizationStatus) {
kCLAuthorizationStatusNotDetermined = 0, 用户未确定
kCLAuthorizationStatusRestricted, 受限
kCLAuthorizationStatusDenied, 被拒绝
kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(NA, 8_0),前后台权限
kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0), 前台可用
kCLAuthorizationStatusAuthorized // 过期,等同于kCLAuthorizationStatusAuthorizedAlways
};
*/
switch (status) {
case kCLAuthorizationStatusNotDetermined:
NSLog(@"用户未确定");
break;
case kCLAuthorizationStatusRestricted:
NSLog(@"定位受限");
break;
case kCLAuthorizationStatusDenied:{
if ([CLLocationManager locationServicesEnabled]) { // 判断定位是否可用
NSLog(@"定位被开启,但被拒绝");
}else{
NSLog(@"定位关闭,不可用");
}
break;
}
case kCLAuthorizationStatusAuthorizedAlways:
NSLog(@"进入后台");
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
NSLog(@"进入前台");
break;
default:
break;
}
}
// 前台定位和iOS8一致
// 后台定位方法一:在配置完后台定位后需设置如下属性
_manager.allowsBackgroundLocationUpdates = YES;
// 注意:如果APP处于后台,则会出现蓝条
// 方法二和iOS8一致
// 作用:按照定位精确度从低到高进行排序,逐个进行定位。如果获取到的位置不是精确度最高的那个,也会在定位超时后,通过代理告诉外界
// 注意:一个要实现代理的定位失败方法; 二:不能与startUpdatingLocation同时使用
[_locationM requestLocation];
- (CLLocationManager *)manager{
if (!_manager) {
_manager = [[CLLocationManager alloc] init];
_manager.delegate = self;
// 请求授权
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
[_manager requestAlwaysAuthorization];
}
}
return _manager;
}
- (void)viewDidLoad{
[super viewDidLoad];
// 开始定位,获取设备朝向
[self.manager startUpdatingHeading];
}
// 代理方法
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
// 获取当前设备的磁北朝向
CLLocationDirection angle = newHeading.magneticHeading;
// 将当前角度转换为弧度值
CGFloat radius = angle / 180.0 * M_PI;
// 旋转指南针
[UIView animateWithDuration:0.25 animations:^{
self.compass.transform = CGAffineTransformMakeRotation(-radius);
}];
}
#import
_locationM = [[CLLocationManager alloc] init];
_locationM.delegate = self;
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0){
[_locationM requestAlwaysAuthorization];
}
// 创建区域中心
CLLocationCoordinate2D coordinate2D = CLLocationCoordinate2DMake(20.0, 120.0);
// 区域半径
CLLocationDistance distance = 1000;
// 创建区域
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:coordinate2D radius:distance identifier:@"广州"];
// 开始请求定位
[self.manager startMonitoringForRegion:region];
#pragma mark - CLLocationManagerDelegate
// 进入区域时调用
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
NSLog(@"进入区域");
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
NSLog(@"离开区域");
}
#import
_geoC = [[CLGeocoder alloc] init];
// 方式一:通过位置名称获取编码信息
- (IBAction)geoc:(id)sender {
NSString *address = self.addressDetailTV.text;
if (!address.length) return;
[self.geoC geocodeAddressString:address completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) {
// 包含区,街道等信息的地标对象
CLPlacemark *placemark = [placemarks firstObject];
// 城市名称
// NSString *city = placemark.locality;
// 街道名称
// NSString *street = placemark.thoroughfare;
// 全称
if(error == nil){
NSString *name = placemark.name;
self.addressDetailTV.text = [NSString stringWithFormat:@"%@", name];
self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
}else{
NSLog(@"编码错误-%@",error);
}
}];
// 方式二:
// 地理编码方案二:根据地址和指定区域两个条件进行地理编码(更加精确)
[self.geoC geocodeAddressString:@"广州" inRegion:nil completionHandler:^(NSArray * __nullable placemarks, NSError * __nullable error) {
// 包含区,街道等信息的地标对象
CLPlacemark *placemark = [placemarks firstObject];
self.addressDetailTV.text = placemark.description;
self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
}];
}
// 反地理编码
- (IBAction)reverse:(id)sender {
/**
参数一:将要反编码的位置
参数二:反编码后的回调
*/
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake([self.latitudeTF.text floatValue], [self.longtitudeTF.text floatValue]);
CLLocation *location = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
[self.geoC reverseGeocodeLocation:location completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) {
CLPlacemark *placemark = [placemarks firstObject];
if(error == nil){
NSString *name = placemark.name;
self.addressDetailTV.text = name;
self.latitudeTF.text = @(placemark.location.coordinate.latitude).stringValue ;
self.longtitudeTF.text = @(placemark.location.coordinate.longitude).stringValue;
}else{
NSLog(@"编码错误-%@",error);
}
}];
}