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
输入查询得出结果


浙公网安备 33010602011771号