UI高级___定位

学习目标:

—定位功能

       在IOS开发中,要加入定位和地图  必须导入2个框架进行开发。

map kit:用于地图展示

core Location:用于地理定位

 

要实现地图、导航功能,往往需要先熟悉定位功能,在iOS中通过Core Location框架进行定位 操作。Core Location自身可以单独使用,和地图开发框架MapKit完全是独立的,

但是往往地图开发要配合定位框架使用。在Core Location中主要包含了定位、地理编码(包括反编码)功能。 

 定位功能

#import "ViewController.h"

#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>
@property (nonatomic, strong)CLLocationManager *manager;
@end

@implementation ViewController

//使用定位之前  先导入CoreLocation.framework框架 在相应的类中导入CoreLocation/CoreLocation.h


- (void)viewDidLoad {
    [super viewDidLoad];
//判断服务器是否打开
    BOOL isOpen = [CLLocationManager locationServicesEnabled];
    
    if (isOpen) {
        NSLog(@"定位服务打开");
    }else{
        
        NSLog(@"亲,您手机定位服务没打开");
    }
    


//判断认证状态
/*
1.用户没有做出任何判断
      kCLAuthorizationStatusNotDetermined = 0,
2.用户禁用位置服务信息
      kCLAuthorizationStatusDenied = 2
3.在后台访问位置服务
      kCLAuthorizationStatusAuthorizedAlways = 3 NS_ENUM_AVAILABLE(NA, 8_0)——————此枚举值是在iOS8.0之后添加上的,就是iOS7,6,...没有这个枚举值,
4.在前台访问位置服务
      kCLAuthorizationStatusAuthorizedWhenInUse = 4
*/
    
    //获取认证状态
    NSInteger stuatus = [CLLocationManager authorizationStatus];
    NSLog(@"%ld",stuatus);
    
    switch (stuatus) {
        case 0:
            NSLog(@"kCLAuthorizationStatusNotDetermined--没有决定");
            break;
        case 1:
            NSLog(@"kCLAuthorizationStatusRestricted--没有许可");
            break;
        case 2:
            NSLog(@"kCLAuthorizationStatusDenied--禁止使用");
            break;
        case 3:
            NSLog(@"kCLAuthorizationStatusAuthorizedAlways--始终允许");
            break;
        case 4:
            NSLog(@"kCLAuthorizationStatusAuthorizedWhenInUse--开启允许");
            break;
            
        default:
            break;
    }
    
    
    //3.请求app访问手机的定位服务
    // 3.1 修改plist文件
    //NSLocationAlwaysUsageDescription---我想在后台还访问您的位置
    //NSLocationWhenInUseUsageDescription---我想在我的app开启的时候使用您的位置,可以吗?
    _manager = [[CLLocationManager alloc]init];
    _manager.delegate = self;
    float version = [[[UIDevice currentDevice] systemVersion] floatValue];
        NSLog(@"%f %@",version,[[UIDevice currentDevice] systemName]);
    if (version >= 8.0) {
        [_manager requestAlwaysAuthorization];
    }
}

//  用户许可状态改变的时候调用此方法
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    NSLog(@"认证状态改变");   
}
@end

实现定位 和定位功能地理方法 需要导入CoreLocation.framework和修改plist文件;

#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>
@property (nonatomic, strong)CLLocationManager *manager;
@end

@implementation ViewController

//懒加载

-(CLLocationManager *)manager
{
    if(!_manager){
        
        _manager = [[CLLocationManager alloc]init];
        _manager.delegate = self;
        
    }
    return _manager;
    
}


- (void)viewDidLoad {
    [super viewDidLoad];

    if (![CLLocationManager locationServicesEnabled]) {
        NSLog(@"手机定位服务没有打开");
        return ;
    }
    //如果用户没有授权
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
        
//        手机系统版本
        if ([[[UIDevice currentDevice] systemVersion] floatValue] >=8.0  ) {
            //调用此方法之前必须在plist文件中添加NSLocationWhenInUseUsageDescription --string-- 后面跟的文字就是提示信息
            //请求用户授权
            [self.manager requestAlwaysAuthorization];
            
        }
    }else if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse){
        //做定位服务
        //开启定位
        [self.manager startUpdatingLocation];
        //开启追踪导航方向
        [self.manager startUpdatingHeading];
        //关闭
        [self.manager stopUpdatingHeading];
        //开启区域追踪
        CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(39.0, 190);
        
        CLCircularRegion *region = [[CLCircularRegion alloc]initWithCenter:coordinate radius:1000 identifier:@"haha"];
        [self.manager startMonitoringForRegion:region];
    }
}

#pragma mark-CLLocationManagerDelegate
//位置发生变化的时候开始调用这个方法,默认没个一段时间就会调用一次
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    CLLocation *location = [locations lastObject];
    NSLog(@"--updating location longitude:%f  latitude:%f",location.coordinate.longitude,location.coordinate.latitude);
    
    NSLog(@"%@",location.description);
    //如果不需要时时定位,使用完关闭定位服务;
//        [self.manager stopUpdatingLocation];
    
    
    
}
/*
 方向: 0 ~ 359.9 , 0 代表正北
 @property(readonly, nonatomic) CLLocationDirection course

 速度:m/s
 @property(readonly, nonatomic) CLLocationSpeed speed

 获取两个位置之间的距离
 - (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
 */


//导航方向发生变化的时候执行此方法
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
    NSLog(@"导航方向发生变化的时候执行此方法");
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"进入到该区域");
    
}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region{
    
    NSLog(@"离开该区域");
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

 地理编码

除了提供位置跟踪功能之外,在定位服务中还包含CLGeocoder类用于处理地理编码和逆地理编码 (又叫反地理编码)功能。 

地理编码:根据给定的位置(通常是地名)确定地理坐标(经、纬度)。 逆地理编码:可以根据地理坐标(经、纬度)确定位置信息(街道、门牌等)。 

代码演示。

#import "ViewController.h"
//需要导入 CoreLocation.framework
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()

@property (nonatomic, strong)CLGeocoder *geocode;
//地理编码
@property (weak, nonatomic) IBOutlet UITextField *adress;
@property (weak, nonatomic) IBOutlet UITextField *longtitude;
@property (weak, nonatomic) IBOutlet UITextField *latitude;
@property (weak, nonatomic) IBOutlet UILabel *datailAdress;
//反地理编码
@property (weak, nonatomic) IBOutlet UITextField *reverseLongTitude;
@property (weak, nonatomic) IBOutlet UITextField *reverseLaTitude;
@property (weak, nonatomic) IBOutlet UILabel *reverAdress;


@end

@implementation ViewController

- (CLGeocoder *)geocode
{
    if (!_geocode) {
        _geocode = [[CLGeocoder alloc]init];
        
    }
    return _geocode;
    
}


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)geocode:(id)sender {
    NSString *address = self.adress.text;
    //进行编码
    [self.geocode geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        //如果有误  直接返回
        if (error) {
            NSLog(@"您输入的地址有误");
            return ;
        }
        //如果没错
        //读出经纬度
        CLPlacemark *placemark = [placemarks lastObject];
        //精度
        CLLocationDegrees lon = placemark.location.coordinate.longitude;
        //纬度
        CLLocationDegrees lat = placemark.location.coordinate.latitude;
        //给文本框赋值
        self.longtitude.text = [NSString stringWithFormat:@"%f",lon];
        self.latitude.text = [NSString stringWithFormat:@"%f",lat];
        self.datailAdress.text = placemark.name;
        
        //placemarks数组中存放着编码后的位置信息
        [placemarks enumerateObjectsUsingBlock:^(CLPlacemark * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSLog(@"——————————%ld————————————",idx);
            NSLog(@"%@",obj.locality);
            NSLog(@"%@",obj.name);
        }];
    }];
    
    
}
#pragma mark- 地理反编码:将经纬度编码成地区

- (IBAction)reverseGeocode:(id)sender {
    CLLocationDegrees longItude = [self.reverseLongTitude.text floatValue];
    CLLocationDegrees latitude = [self.reverseLaTitude.text floatValue];
    
    CLLocation *location = [[CLLocation alloc]initWithLatitude:latitude longitude:longItude];
    
    [self.geocode reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (error) {
            NSLog(@"你输入的位置有误");
            self.reverAdress.text = @"没有找到该位置";
            return ;
        }
           //取出位置
            CLPlacemark *mark = [placemarks lastObject];
            self.reverAdress.text = mark.name;
            [placemarks enumerateObjectsUsingBlock:^(CLPlacemark * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                NSLog(@"——————————%ld————————————",idx);
                NSLog(@"%@",obj.locality);
                NSLog(@"%@",obj.name);

            }];
    }];
    
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

 输入查询得出结果 

 

 

 

posted on 2015-10-23 15:44  进_无止境  阅读(183)  评论(0)    收藏  举报

导航