iOS UI进阶-4.0 地图与定位
2015-09-30 22:28 jiangys 阅读(343) 评论(0) 编辑 收藏 举报- 导航:去任意陌生的地方
- 周边:找餐馆、找酒店、找银行、找电影院
- Map Kit :用于地图展示
- Core Location :用于地理定位
- LBS :Location Based Service
- SoLoMo :Social Local Mobile(索罗门)
定位实现
步骤:
1.导入头文件
#import <CoreLocation/CoreLocation.h>
2.创建定位管理者,使用懒加载,只创建一个。
3.设置代理,监听是否授权成功
4.开始定位
如果是iOS8设置授权
#import "ViewController.h" #import <CoreLocation/CoreLocation.h> @interface ViewController ()<CLLocationManagerDelegate> /** * 1.定位管理者 */ @property (nonatomic ,strong) CLLocationManager *mgr; @end @implementation ViewController #pragma mark - 懒加载 - (CLLocationManager *)mgr { if (!_mgr) { _mgr = [[CLLocationManager alloc] init]; } return _mgr; } - (void)viewDidLoad { [super viewDidLoad]; // 2.成为CoreLocation管理者的代理监听获取到的位置 self.mgr.delegate = self; /* 注意: iOS7只要开始定位, 系统就会自动要求用户对你的应用程序授权. 但是从iOS8开始, 想要定位必须先"自己""主动"要求用户授权 在iOS8中不仅仅要主动请求授权, 而且必须再info.plist文件中配置一项属性才能弹出授权窗口 NSLocationWhenInUseDescription,允许在前台获取GPS的描述 NSLocationAlwaysUsageDescription,允许在后台获取GPS的描述 */ // 判断是否是iOS8 if([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) { NSLog(@"是iOS8"); // 主动要求用户对我们的程序授权, 授权状态改变就会通知代理 [self.mgr requestAlwaysAuthorization]; // 请求前台和后台定位权限 }else //iOS7 { // 3.开始监听(开始获取位置) [self.mgr startUpdatingLocation]; } } /** * 授权状态发生改变时调用 * * @param manager 触发事件的对象 * @param status 当前授权的状态 */ - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { /* 用户从未选择过权限 kCLAuthorizationStatusNotDetermined 无法使用定位服务,该状态用户无法改变 kCLAuthorizationStatusRestricted 用户拒绝该应用使用定位服务,或是定位服务总开关处于关闭状态 kCLAuthorizationStatusDenied 已经授权(废弃) kCLAuthorizationStatusAuthorized 用户允许该程序无论何时都可以使用地理信息 kCLAuthorizationStatusAuthorizedAlways 用户同意程序在可见时使用地理位置 kCLAuthorizationStatusAuthorizedWhenInUse */ if (status == kCLAuthorizationStatusNotDetermined) { NSLog(@"等待用户授权"); }else if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse) { NSLog(@"授权成功"); // 开始定位 [self.mgr startUpdatingLocation]; }else { NSLog(@"授权失败"); } } #pragma mark - CLLocationManagerDelegate /** * 获取到位置信息之后就会调用(调用频率非常高) * * @param manager 触发事件的对象 * @param locations 获取到的位置 */ - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { NSLog(@"%s", __func__); // 如果只需要获取一次, 可以获取到位置之后就停止 // [self.mgr stopUpdatingLocation]; } @end
CLGeocoder
- (void)geocodeBtnClick { // 0.获取用户输入的位置 NSString *addressStr = self.addressField.text; if (addressStr == nil || addressStr.length == 0) { NSLog(@"请输入地址"); return; } // 1.创建地理编码对象 // 2.利用地理编码对象编码 // 根据传入的地址获取该地址对应的经纬度信息 [self.geocoder geocodeAddressString:addressStr completionHandler:^(NSArray *placemarks, NSError *error) { if (placemarks.count == 0 || error != nil) { return ; } // placemarks地标数组, 地标数组中存放着地标, 每一个地标包含了该位置的经纬度以及城市/区域/国家代码/邮编等等... // 获取数组中的第一个地标 CLPlacemark *placemark = [placemarks firstObject]; self.latitudeLabel.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude]; self.longitudeLabel.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude]; NSArray *address = placemark.addressDictionary[@"FormattedAddressLines"]; NSMutableString *strM = [NSMutableString string]; for (NSString *str in address) { [strM appendString:str]; } self.detailAddressLabel.text = strM; }]; }
- (void)reverseGeocode { // 1.获取用户输入的经纬度 NSString *longtitude = self.longtitudeField.text; NSString *latitude = self.latitudeField.text; if (longtitude.length == 0 || longtitude == nil || latitude.length == 0 || latitude == nil) { NSLog(@"请输入经纬度"); return; } // 2.根据用户输入的经纬度创建CLLocation对象 CLLocation *location = [[CLLocation alloc] initWithLatitude:[latitude doubleValue] longitude:[longtitude doubleValue]]; // 3.根据CLLocation对象获取对应的地标信息 [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { for (CLPlacemark *placemark in placemarks) { NSLog(@"%@ %@ %f %f", placemark.name, placemark.addressDictionary, placemark.location.coordinate.latitude, placemark.location.coordinate.longitude); self.reverseDetailAddressLabel.text = placemark.locality; } }]; }
地图
直接使用百度地图API吧,相关笔记
百度地图API 最新版本是2.4.1,需要关注,不支持64位
注:静态库中采用ObjectC++实现,因此需要您保证您工程中至少有一个.mm后缀的源文件
1> 没有64位架构的支持
libbaidumapapi.a, missing required architecture x86_64
.a文件缺少64位的架构
解决办法:将Architectures修改位:$(ARCHS_STANDARD_32_BIT)
2> 如果在导入第三方框架时,发现提示"std::"提示错误,说明框架使用了C++
解决办法,随便把项目中的一个文件,扩展名.mm
.m c语言&OC混编
.mm c++语言&OC混编
.c 纯C语言
.cpp 纯C++
3> 百度地图api的特点,代理方法,通常以onXXX,表示发生了什么事件时。。。
4> 关于error的数字
0 表示正确
其他数字,表示错误代码
5> 自2.0.0起,BMKMapView新增viewWillAppear、viewWillDisappear方法来控制BMKMapView的生命周期,并且在一个时刻只能有一个BMKMapView接受回调消息
因此在使用BMKMapView的viewController中需要在viewWillAppear、viewWillDisappear方法中调用BMKMapView的对应的方法,并处理delegate,代码如下
6> POI检索:周边检索、区域检索和城市内检索
苹果原生地图框架不支持的功能