地图和定位 、 iCloud
1 FindMe应用
1.1 问题
MapKit框架可以用于创建现场交互的地图来显示用户想要设备显示的任何位置,包括用户的当前位置,甚至可以进行标记并查看地图上的标注信息。CoreLocation框架主要用于确定物理位置,通过三种技术来实现:GPS、蜂窝基站定位和WPS,GPS是这三种中最精确。本案例使用MapKit和CoreLocation框架完成一款地图应用,显示自身的位置并添加视图标注,如图-1所示:
图-1
1.2 方案
首先创建一个SingleViewApplication应用,需要将CoreLocation和MapKit框架添加到项目中。
然后在Storyboard文件中搭建界面,从对象库中拖拽一个MapView控件到场景中,调整地图视图的尺寸使宽度占满整个大视图,通过连线的方式将MapView控件的delegate设置为ViewController。
场景的下方再拖放一个Label控件和Button控件。分别将场景中的MapView控件、Label控件以及Button控件关联成ViewController的输出口属性mapView、progressLabel和button,另外再将Button控件关联成ViewController的动作方法findMe:,当点击按钮时该方法被调用开始更新定位。
接下来创建一个类Annotation用来保存标注对象,该类有一个必须的属性CLLocationCoordinate2D类型的coordinate,用来记录标注的位置,然后通过重写属性title和subTitle的setter方法设置标题和子标题的内容。
完成以上步骤后在ViewController类扩展中定义一个CLLocationManager类型的locationManager属性,并且ViewController需要遵守MKMapViewDelegate和CLLocationManagerDelegate协议。在viewDidLoad方法中将self.mapView的showsUserLocation属性设置为YES,允许显示当前用户的位置。
然后实现findMe:方法,该方法中设置self.locationManager的相关属性并将delegate设置为ViewController,通过调用startUpdatingLocation方法开始更新地图数据,然后更新label的显示内容。
接下来实现locationManager:didUpdateLocations:协议方法,该方法在每次更新位置时调用,该方法中通过locations参数获取到当前位置,并通过当前位置创建一个显示区域,添加标注更新label的显示内容。
最后实现mapView:viewForAnnotation:协议方法,当mapView需要一个标注视图时将调用该方法,在该方法中创建一个标注视图,并添加到地图上。
1.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:搭建界面
首先创建一个SingleViewApplication应用,需要将CoreLocation和MapKit框架添加到项目中。
然后在Storyboard文件中搭建界面,从对象库中拖拽一个MapView控件到场景中,调整地图视图的尺寸使宽度占满整个大视图,通过连线的方式将MapView控件的delegate设置为ViewController,如图-2所示:
图-2
场景的下方再拖放一个Label控件和Button控件。分别将场景中的MapView控件、Label控件以及Button控件关联成ViewController的输出口属性mapView、progressLabel和button,另外再将Button控件关联成ViewController的动作方法findMe:,当点击按钮时该方法被调用开始更新定位,代码如下所示:
- @interface ViewController ()
- @property (weak, nonatomic) IBOutlet MKMapView *mapView;
- @property (weak, nonatomic) IBOutlet UILabel *progressLabel;
- @property (weak, nonatomic) IBOutlet UIButton *button;
- @end
在Storyboard中完成的界面如图-3所示:
图-3
步骤二:创建标注类Annotation
创建一个类Annotation用来保存标注对象,该类继承至NSObjet,它有一个必须的属性CLLocationCoordinate2D类型的coordinate,用来记录标注的位置,然后通过重写属性title和subTitle的setter方法设置标题和子标题的内容,代码如下所示:
- //Annotation.h文件
- @interface Annotation : NSObject<MKAnnotation>
- @property (nonatomic,assign) CLLocationCoordinate2D coordinate;
- @end
- //Annotation.m文件
- @implementation Annotation
- -(NSString *)title {
- NSString *string = @"You are here";
- return string;
- }
- -(NSString *)subtitle {
- NSString *string = @"您当前位置";
- return string;
- }
- @end
步骤三:实现地图定位和添加标注视图
在ViewController类扩展中定义一个CLLocationManager类型的locationManager属性,并且ViewController需要遵守MKMapViewDelegate和CLLocationManagerDelegate协议,代码如下所示:
- @interface ViewController ()<MKMapViewDelegate,CLLocationManagerDelegate,UIAlertViewDelegate>
- @property (weak, nonatomic) IBOutlet MKMapView *mapView;
- @property (weak, nonatomic) IBOutlet UILabel *progressLabel;
- @property (weak, nonatomic) IBOutlet UIButton *button;
- @property (nonatomic,strong) CLLocationManager *locationManager;
- @end
- //初始化属性locationManager
- -(CLLocationManager *)locationManager {
- if (!_locationManager) {
- _locationManager = [[CLLocationManager alloc]init];
- }
- return _locationManager;
- }
在viewDidLoad方法中设置self.mapView的类型,并将self.mapView的showsUserLocation属性设置为YES,允许显示当前用户的位置,代码如下所示:
- - (void)viewDidLoad {
- [super viewDidLoad];
- self.mapView.mapType = MKMapTypeStandard;
- self.mapView.showsUserLocation = YES;
- }
然后实现findMe:方法,该方法中设置self.locationManager的相关属性并将delegate设置为ViewController,通过调用startUpdatingLocation方法开始更新地图数据,然后更新label的显示内容,代码如下所示:
- - (IBAction)findMe:(UIButton *)sender {
- //设置委托对象
- self.locationManager.delegate = self;
- //设置最佳精确度
- self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
- //开始更新
- [self.locationManager requestAlwaysAuthorization];
- [self.locationManager requestWhenInUseAuthorization];
- [self.locationManager startUpdatingLocation];
- //设置标签显示内容
- self.progressLabel.text = @"Delermining Current Location";
- sender.hidden = YES;
- }
接下来实现locationManager:didUpdateLocations:协议方法,该方法在每次更新位置时调用,该方法中通过locations参数获取到当前位置,并通过当前位置创建一个显示区域,添加标注更新label的显示内容,代码如下所示:
- -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
- //获取当前位置
- CLLocation *newLocation = locations[0];
- NSLog(@"%@",newLocation);
- //设置显示区域
- MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000);
- //调整区域以适合地图视图显示的宽高比
- MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];
- //将调整后的区域显示在地图视图上面
- [self.mapView setRegion:adjustedRegion animated:YES];
- manager.delegate = self;
- //由于更新位置是一个比较耗电量的操作,在不必要更新时可以关闭locationManager
- [manager stopUpdatingLocation];
- //更新标签显示
- self.progressLabel.text = @"Recerse Geocoding Location";
- //添加标注
- Annotation *annotation = [[Annotation alloc]init];
- annotation.coordinate = newLocation.coordinate;
- [self.mapView addAnnotation:annotation];
- self.progressLabel.text = @"Location Determined";
- }
最后实现mapView:viewForAnnotation:协议方法,当mapView需要一个标注视图时将调用该方法,在该方法中创建一个标注视图,并添加到地图上,代码如下所示:
- -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
- static NSString *placemarkIdentifier = @"Map Location Identifier";
- if ([annotation isKindOfClass:[Annotation class]]) {
- MKPinAnnotationView *annotationView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:placemarkIdentifier];
- if (!annotationView) {
- annotationView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:placemarkIdentifier];
- }else {
- annotationView.annotation = annotation;
- }
- annotationView.enabled = YES;
- annotationView.animatesDrop = YES;
- annotationView.pinColor = MKPinAnnotationColorPurple;
- annotationView.canShowCallout = YES;
- //为了能够看到显示过程延迟5秒将标注视图添加到界面上
- [self performSelector:@selector(openCallout:) withObject:annotation afterDelay:5];
- self.progressLabel.text = @"Creating Annotation";
- return annotationView;
- }
- return nil;
- }
- //选中标注
- -(void)openCallout:(id<MKAnnotation>)annotation {
- self.progressLabel.text = @"Show Annotation";
- [self.mapView selectAnnotation:annotation animated:YES];
- }
当遇到错误和警告时同样可以通过实现MKMapViewDelegate协议和CLLocationManagerDelegate协议中的方法来提醒用户,代码如下所示:
- -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
- NSString *errorType = (error.code == kCLErrorDenied)?@"Access Denied":@"Unknow Error";
- UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"Error getting Location" message:errorType delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
- [av show];
- }
- -(void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error {
- UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"Error loading map" message:[error description] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
- [av show];
- NSLog(@"%@",[error description]);
- }
- //UIAlertViewDelegate
- -(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
- self.progressLabel.text = @"";
- self.button.hidden = NO;
- }
完成效果如图-4、图-5、图-6所示:
图-4
图-5
图-6
1.4 完整代码
本案例中,ViewController.m文件中的完整代码如下所示:
- #import "ViewController.h"
- #import "Annotation.h"
- @interface ViewController ()<MKMapViewDelegate,CLLocationManagerDelegate,UIAlertViewDelegate>
- @property (weak, nonatomic) IBOutlet MKMapView *mapView;
- @property (weak, nonatomic) IBOutlet UILabel *progressLabel;
- @property (weak, nonatomic) IBOutlet UIButton *button;
- @property (nonatomic,strong) CLLocationManager *locationManager;
- @end
- @implementation ViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- self.mapView.mapType = MKMapTypeStandard;
- self.mapView.showsUserLocation = YES;
- }
- -(CLLocationManager *)locationManager {
- if (!_locationManager) {
- _locationManager = [[CLLocationManager alloc]init];
- }
- return _locationManager;
- }
- - (IBAction)findMe:(UIButton *)sender {
- //设置委托对象
- self.locationManager.delegate = self;
- //设置最佳精确度
- self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
- //开始更新
- [self.locationManager requestAlwaysAuthorization];
- [self.locationManager requestWhenInUseAuthorization];
- [self.locationManager startUpdatingLocation];
- //设置标签显示内容
- self.progressLabel.text = @"Delermining Current Location";
- sender.hidden = YES;
- }
- //CLLocationManagerDelegate协议方法
- -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
- //获取当前位置
- CLLocation *newLocation = locations[0];
- NSLog(@"%@",newLocation);
- //设置显示区域
- MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000);
- //调整区域以适合地图视图显示的宽高比
- MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];
- //将调整后的区域显示在地图视图上面
- [self.mapView setRegion:adjustedRegion animated:YES];
- manager.delegate = self;
- //由于更新位置是一个比较耗电量的操作,在不必要更新时可以关闭locationManager
- [manager stopUpdatingLocation];
- //更新标签显示
- self.progressLabel.text = @"Recerse Geocoding Location";
- //添加标注
- Annotation *annotation = [[Annotation alloc]init];
- annotation.coordinate = newLocation.coordinate;
- [self.mapView addAnnotation:annotation];
- self.progressLabel.text = @"Location Determined";
- }
- -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
- NSString *errorType = (error.code == kCLErrorDenied)?@"Access Denied":@"Unknow Error";
- UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"Error getting Location" message:errorType delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
- [av show];
- }
- //MapViewDelegate方法
- //当mapView需要一个标注视图时将调用该方法,在该方法中创建一个标注视图
- -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
- static NSString *placemarkIdentifier = @"Map Location Identifier";
- if ([annotation isKindOfClass:[Annotation class]]) {
- MKPinAnnotationView *annotationView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:placemarkIdentifier];
- if (!annotationView) {
- annotationView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:placemarkIdentifier];
- }else {
- annotationView.annotation = annotation;
- }
- annotationView.enabled = YES;
- annotationView.animatesDrop = YES;
- annotationView.pinColor = MKPinAnnotationColorPurple;
- annotationView.canShowCallout = YES;
- //为了能够看到显示过程延迟5秒将标注视图添加到界面上
- [self performSelector:@selector(openCallout:) withObject:annotation afterDelay:5];
- self.progressLabel.text = @"Creating Annotation";
- return annotationView;
- }
- return nil;
- }
- //选中标注
- -(void)openCallout:(id<MKAnnotation>)annotation {
- self.progressLabel.text = @"Show Annotation";
- [self.mapView selectAnnotation:annotation animated:YES];
- }
- -(void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error {
- UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"Error loading map" message:[error description] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
- [av show];
- NSLog(@"%@",[error description]);
- }
- //UIAlertViewDelegate
- -(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
- self.progressLabel.text = @"";
- self.button.hidden = NO;
- }
- @end
本案例中,Annotation.h文件中的完整代码如下所示:
- #import <Foundation/Foundation.h>
- #import <MapKit/MapKit.h>
- @interface Annotation : NSObject<MKAnnotation>
- @property (nonatomic,assign) CLLocationCoordinate2D coordinate;
- @end
本案例中,Annotation.m文件中的完整代码如下所示:
- #import "Annotation.h"
- @implementation Annotation
- -(NSString *)title {
- NSString *string = @"You are here";
- return string;
- }
- -(NSString *)subtitle {
- NSString *string = @"您当前位置";
- return string;
- }
- @end
地图和定位 、 iCloud的更多相关文章
- iOS开发系列--地图与定位
概览 现在很多社交.电商.团购应用都引入了地图和定位功能,似乎地图功能不再是地图应用和导航应用所特有的.的确,有了地图和定位功能确实让我们的生活更加丰富多彩,极大的改变了我们的生活方式.例如你到了一个 ...
- iOS开发之地图与定位
无论是QQ还是微信的移动客户端都少不了定位功能,之前在微信demo中没有添加定位功能,今天就写个定位的小demo来了解一下定位和地图的东西.地图和定位看上去是挺高大上一东西,其实用法比TableVie ...
- [OC][地图] 高德地图之定位初探(一)
使用前的说明 高德地图开放平台的iOS定位模块网址-->http://lbs.amap.com/api/ios-location-sdk/summary/ 高德地图有Web端.android平台 ...
- iOS进阶_地图上定位的标志——大头针
一.添加大头针 地图使用的框架是MapKit 大头针走的是MKAnnotation协议 /* 注意:因为是满足协议MKAnnotation,所以没有MKAnnotation的系统大头针类,必须自定义大 ...
- 地图、定位 CLLocationManager CLGeocoder CLPlacemark
地图.定位 一.基本知识点 定位: 1.info.plist文件设置 ios8以后,使用定位需要在info.plist文件中添加两个字段NSLocationAlwaysUsageDescription ...
- Android 百度地图API 定位 导航
看看这个利用百度地图定位并实现目的地导航的Demo. 首先看实现效果: 进 入后首先会得到当前位置,在地图上显示出来.在输入框中输入目的地后,就会在地 ...
- ios开发——实用技术OC篇&地图与定位
地图与定位 11.1 iOS定位服务 11.2 iOS地图 11.3 Web地图 1 iOS定位服务 iOS中有三个定位服务组件: Wifi定位,通过查询一个Wifi路由器的地理位置的信息.比较省电, ...
- 在Fragment中实现百度地图,定位到当前位置(基于SDKv2.1.0)
使用最新版本的百度地图需要注意的几个地方: 1.libs文件夹下要有android-support-v4.jar.baidumapapi_v2_1_0.jar.locSDK_3.1.jar三个jar包 ...
- iOS中的地图和定位
文章摘自http://www.cnblogs.com/kenshincui/p/4125570.html#location 如有侵权,请联系删除. 概览 现在很多社交.电商.团购应用都引入了地图和定 ...
- AngularJS进阶(十九)在AngularJS应用中集成百度地图实现定位功能
在AngularJS应用中集成百度地图实现定位功能 注:请点击此处进行充电! 前言 根据项目需求,需要实现手机定位功能,考虑到百度业务的强大能力,遂决定使用百度地图第三方服务. 添加第三方模块的步骤与 ...
随机推荐
- XAF响应式布局皮肤界面展示
XAF为了对手机.平板电脑的支持,增加了新的响应式布局皮肤支持,这个功能已经出来很久了,对于平板电脑.PC的支持已经很不错了,对于手机的界面还不是很完美. 本篇展示一下当前的效果,让有需要的同学.还没 ...
- 《BI项目笔记》创建时间维度(2)
创建步骤: 序号 选择的属性 重命名后的名称 属性类别 1 DateKey DateKey 常规 2 Month Key Month Key 月份 3 English Month Name Eng ...
- sublime_text3配置
推荐视频 http://v.youku.com/v_show/id_XMzU5NzQ5ODgw.html 介绍的是2版本 准备工作 点击连接下载Sublime Text3 初始化用户信息 第一次安装该 ...
- php 对多维数组排序array_multisort
php 对多维数组排序array_multisort 排序顺序标志: SORT_ASC - 按照上升顺序排序 SORT_DESC - 按照下降顺序排序 排序类型标志: SORT_REGULAR - 将 ...
- mysql 基础篇1
1 引入 数据保存到内存: 优点: 1)读写非常快 缺点: 1)程序关闭导致数据丢失 数据保存到文件: 优点: 1)数据可以永久保存 缺点: 1)频繁地IO操作,效率不高! 2)数据管理不方便.例如查 ...
- CSS3中的Transition属性详解
w3c标准中对CSS3的transition这是样描述的:“CSS的transition允许CSS的属性值在一定的时间区间内平滑地过渡.这种效果可以在鼠标单击.获得焦点.被点击或对元素任何改变中触发, ...
- js实现input输入框只能输入数字的功能(完美测试通过)
<input type="text" style="ime-mode:disabled;" onpaste="return false;&quo ...
- Excel 2013中单元格添加下拉列表的方法
使用Excel录入数据的时候我们通常使用下拉列表来限定输入的数据,这样录入数据就很少发生错误了.Excel 2013较以前的版本发生了很大的变化,那么在Excel 2013是如何添加下拉列表的呢? 下 ...
- css优雅降级和渐进增强
今天看前端公众号发布的文章,学到了几个新词 1.modernizr 2.@support 3.优雅降级 其中第三个“优雅降级”,如此文艺的名字居然还是第一次听到.度娘了一下,发现[优雅降级],[渐进增 ...
- 樱花漫地集于我心,蝶舞纷飞祈愿相随---总结 顕出:void-sampling 显示:void-sampling
知识点: 分支语句,四则运算,( ̄y▽ ̄)~* 实验过程中遇到的问题及解决方法: 忘记换行,忘记代码,输入法切换(´∀`*) 暂时还得照书写,*★,°*:.☆\( ̄▽ ̄)/$:*.°★* 实验心得体会 ...