定位功能的实现,使用了Core Location ,其提供了实现位置感知能力所需的全部功能
1、位置追踪;
2、监控显著的位置变化;
3、监控自定义区域的进入与离开;
4、获取当前的朝向;
5、将坐标转换为地址,即正向地理编码;
6、将地址转换为坐标,即反向地理编码;
定位的使用
获取经纬度,并根据经纬度进行反编译获得中文显示位置信息
步骤1
导入框架 CoreLocation.framework
导入方法:项目名称-项目-build phases-link binary with libraries-"+”
步骤2
导入头文件并设置代理"CLLocationManagerDelegate"
#import <CoreLocation/CoreLocation.h>
#import <CoreLocation/CLLocationManager.h>
代码示例
1、接口文件
#import <UIKit/UIKit.h>
//导入位置位置头文件
#import <CoreLocation/CoreLocation.h>
#import <CoreLocation/CLLocationManager.h>
@interface CurrentLocationVC : UIViewController <CLLocationManagerDelegate, UITextFieldDelegate>
@end
2、实现文件
#import "CurrentLocationVC.h"
@interface CurrentLocationVC ()
{
// 当前地理位置
CLLocationManager *locationManager;
CLGeocoder *geocoder;
// 位置信息
NSString *addressString;
}
@end
@implementation CurrentLocationVC
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// 设置导航栏标题
[self.navigationItem setTitle:@"定位"];
// 创建视图
[self setUI];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)loadView
{
[super loadView];
// 设置背景颜色
[self.view setBackgroundColor:[UIColor whiteColor]];
}
#pragma mark - setUI
- (void)setUI
{
// 获取位置-根据坐标获得地名
UIButton *addressBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.view addSubview:addressBtn];
[addressBtn setFrame:CGRectMake((self.view.frame.size.width - 120.0) / 2, 10.0, 120.0, 44.0)];
[addressBtn setBackgroundColor:[UIColor orangeColor]];
[addressBtn setTitle:@"获取位置" forState:UIControlStateNormal];
[addressBtn addTarget:self action:@selector(getCurrentLocation:) forControlEvents:UIControlEventTouchUpInside];
}
#pragma mark - 坐标转换位置
// 获得位置信息
- (void)getCurrentLocation:(UIButton *)button
{
// 开始定位
[self startLocationManager];
}
// 地理位置回调方法
#pragma mark - CLLocationManagerDelegate 位置更新
// 开始定位
- (void)startLocationManager
{
// 不存在时初始化实例
if (locationManager == nil)
{
locationManager = [[CLLocationManager alloc] init];
}
// 是否开启地理位置的服务
if ([CLLocationManager locationServicesEnabled])
{
// 设置当前类为其代理
[locationManager setDelegate:self];
// 设置用户使用类型(ios6及以上),置为步行或跑步模式
if ([locationManager respondsToSelector:@selector(setActivityType:)])
{
locationManager.activityType = CLActivityTypeFitness;
}
// 设置位置精确度 最佳精确度
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
// 设置距离精确度 即设备移动多少米就通过委托通知设备新的位置
[locationManager setDistanceFilter:100.0f];
// 开启开始定位
// 方法1
[locationManager startUpdatingLocation];
// 启动后提示
NSLog(@"正在获取当前位置...");
}
else
{
[[[UIAlertView alloc] initWithTitle:@"温馨提醒" message:@"定位未打开,请打开定位服务" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil] show];
}
}
// 停止定位
- (void)stopLocationManager
{
[locationManager stopUpdatingLocation];
}
// 获取定位信息(ios6)
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// 获取经纬度
CLLocation *newLocation = [locations lastObject];
// %f-%g\u00b0
NSMutableString *string = [NSMutableString stringWithFormat:@"经度:%g\u00b0/纬度:%g\u00b0",newLocation.coordinate.latitude,newLocation.coordinate.longitude];
NSLog(@"经纬度:%@", string);
// 位置更新的最近的时间(Core Location在锁定新的位置前,它会将上一次已知的位置作为第一次调用委托方法的结果展示出来,当需要知道现在在什么位置时,通知不必处理表示设备历史位置的位置对象,因此有必要过滤掉30秒以上的位置事件)
NSTimeInterval eventInterval = [newLocation.timestamp timeIntervalSinceNow];
if (abs(eventInterval) < 30.0)
{
// 判断位置精度是否有效 horizontalAccuracy表示位置所在的圆圈的半径(单位:米);verticalAccuracy表示在高度方向上可能偏移的正负范围(单位:米)
if (newLocation.horizontalAccuracy >= 0 && newLocation.horizontalAccuracy <= 100)
{
NSLog(@"newLocation.description %@", newLocation.description);
}
// 反向地理信息编码
//1 反编码,由经纬度转换成地名
if (geocoder == nil)
{
geocoder = [[CLGeocoder alloc] init];
}
//2 执行新的地理信息编码服务请求的时候,停止现有的请求
if ([geocoder isGeocoding])
{
[geocoder cancelGeocode];
}
//3 执行新的地理信息编码服务请求
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks,NSError *error)
{
// 得到最近的地名
if (placemarks.count > 0)
{
// 获得地理位置信息
CLPlacemark *foundPlacemark = [placemarks objectAtIndex:0];
NSString *foundAddress = [NSString stringWithFormat:@"%@",[[foundPlacemark.addressDictionary valueForKey:@"FormattedAddressLines"] lastObject]];
[[[UIAlertView alloc] initWithTitle:@"温馨提醒" message:foundAddress delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil] show];
}
else if (error.code == kCLErrorGeocodeCanceled)
{
[[[UIAlertView alloc] initWithTitle:@"温馨提醒" message:@"Geocoding cancelled" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil] show];
}
else if (error.code == kCLErrorGeocodeFoundNoResult)
{
[[[UIAlertView alloc] initWithTitle:@"温馨提醒" message:@"No geocode result found" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil] show];
}
else if (error.code == kCLErrorGeocodeFoundPartialResult)
{
[[[UIAlertView alloc] initWithTitle:@"温馨提醒" message:@"Partial geocode result" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil] show];
}
else
{
[[[UIAlertView alloc] initWithTitle:@"温馨提醒" message:error.description delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil] show];
}
}];
// 停止定位
[self stopLocationManager];
}
}
// 定位失败
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
/***********************************************************/
// 用户未开启或不允许定位
if ([error code] == kCLErrorDenied)
{
[[[UIAlertView alloc] initWithTitle:@"温馨提醒" message:@"定位未打开,请打开定位服务" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil] show];
}
// 停止定位
[self stopLocationManager];
}