定位

1.一次定位

  • 1、创建位置管理器

      // 这里创建的管理其对象如果没有强引用,就会造成你后面的操作不会出现效果,全局变量强引用.CLLocationManager *manager = [[CLLocationManager alloc] init];self.manager = manager;
    
  • 2、请求授权

    • 请求授权有三种方式,每种都需要配置info.plist
      第一种,请求应用在使用时(应用在前台运行)可以获取定位信息

        //设置info.plist -> Location When In Use Usage Description[manager requestWhenInUseAuthorization];
      
    • 第二种,请求应用始终(应用在前台&后台运行时)可以获取定位信息 缺点: 应用在后台执行一段时间后就会挂起

        //设置info.plist -> NSLocationAlwaysUsageDescription[mgr requestAlwaysAuthorization];
      
    • 第三种,后台运行模式(应用在任何模式下)获取定位信息 设置info.plist, 还需要代码设置

        //1) **配置info.plist相关key**  ( 这里需要新加一个选项 选择: Required background modes->打开items->选取App registers for location updates(定位后台运行的模式))  — 在ios8 之前只要设置这个就行了//2) 在ios8以后就是**ios9的一个新特性需要再加上一句代码 才能执行这个功能**,即mgr.allowsBackgroundLocationUpdates = YES;
      
    • 第三种除了做以上工作外,还需将第一种前台请求授权打开,也就是需要将第一种授权也同时完整做一遍

      三种方式对比:
      第一种对app有较大限制,应用进入后台就无法获取定位(不建议)
      第二种用户较为反感,可能会被用户禁止定位(不建议)
      第三种是应用程序临时进入后台时也可以请求授权。是较为常用的方式

  • 3、定位(设置代理:CLLocationManagerDelegate)

      manager.delegate = self;
    
  • 4、开始并获取定位

      //开始定位[mgr startUpdatingLocation]
    
  • 5、代理方法回调

    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{//在代理方法中获取位置信息。该方法在获取到位置后自动调用,无论位置是否发生变化   CLLocation *location = locations.lastObject;NSLog(@"%f,%f", location.coordinate.latitude, location.coordinate.longitude);//停止定位[manager stopUpdatingLocation];/*** 无法获取定位的情况:1> mgr没有强引用2> 请求授权没有设置info.plist3> 模拟器没有设置4> 模拟器bug  切换模拟器*/}
    

2.持续定位

持续定位在一次定位的基础上,额外设置两个属性即可:
//优化持续定位
//设置距离筛选器 减少不必要的监听回调
manager.distanceFilter = 10;//设置期望精确度  减少不必要的能耗(精确度要求的越低,手机能耗越小)
manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;

地理编码与反地理编码

1.地理编码

  • 1.创建地理编码者

      CLGeocoder *geocoder = [CLGeocoder new];
    
  • 2.进行地理编码

      //人文-> 地理[geocoder geocodeAddressString:@"地理位置字符串" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {if (placemarks.count == 0 || error) {NSLog(@"%@", error);return ;}//CLPlacemark 地标对象 包含地理信息&人文信息CLPlacemark *pm = placemarks.lastObject;//设置数据self.latitudeLabel.text = [NSString stringWithFormat:@"%f", pm.location.coordinate.latitude];self.longitudeLabel.text = [NSString stringWithFormat:@"%f", pm.location.coordinate.longitude];self.detailLabel.text = pm.name;}];
    

2.反地理编码

  • 1.创建地理编码者

      //地理 -> 人文CLGeocoder *geocoder = [CLGeocoder new];//封装位置对象,根据经纬度创建位置对象CLLocation *location = [[CLLocation alloc]initWithLatitude:[self.latitudeTF.text floatValue] longitude:[self.longitudeTF.text floatValue]];
    
  • 2.进行反地理编码

      [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {if (placemarks.count ==0 || error) {return ;}CLPlacemark *pm = placemarks.lastObject;//设置数据self.cityLabel.text = pm.locality;}];
    

对系统地图的基本使用

1、系统地图基本使用流程:

  • 1,创建MapView ->

    ps:地图相关需要导入MapKit类库,而系统也会根据代码自动导入某些类库(包括MapKit),所以如果运行代码时因为缺少类库报错,则需手动导入,如果没有,那就是系统已经帮你导入了

  • 2,请求授权 ->

    相关定位授权前面有讲

  • 3,设置地图属性,包括:

      //显示定位点self.mapView.showsUserLocation = YES;//设置用户跟踪模式self.mapView.userTrackingMode = MKUserTrackingModeFollow;//显示标尺self.mapView.showsScale = YES;//显示指南针self.mapView.showsCompass = YES;//显示交通self.mapView.showsTraffic = YES;//地图更新到位置后再来进行反地理编码  设置代理self.mapView.delegate = self;//设置地图类型,标准地图,卫星地图,混合地图等self.mapView.mapType = MKMapTypeStandard;
    
  • 4,设置地图位置返回到定位点
    1>第一种方式

      //带动画的设置用户跟踪模式//self.mapView.userTrackingMode = MKUserTrackingModeFollow[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
    

    2>第二种方式

      //设置地图范围  中心点变为定位点,跨度使用当前地图的跨度[self.mapView setRegion:MKCoordinateRegionMake(self.mapView.userLocation.location.coordinate, self.mapView.region.span) animated:YES];/**MKCoordinateRegion是一个结构体* 地图范围  typedef struct {CLLocationCoordinate2D center;  中心点  用于确定地图位置MKCoordinateSpan span;    经纬度跨度    用于确定地图宽高尺寸} MKCoordinateRegion;*/
    
  • 5,地图放大和缩小

    • 地图放大和缩小的原理与上面返回定位点中的第二种方式一样。不同之处在于地图放大缩小时,中心位置不变,地图跨度改变

        //地图的中心点保持不变,地图跨度根据比例系数进行改变MKCoordinateSpan span = MKCoordinateSpanMake(self.mapView.region.span.latitudeDelta * 0.5, self.mapView.region.span.longitudeDelta * 0.5);MKCoordinateRegion region = MKCoordinateRegionMake(self.mapView.region.center, span);[self.mapView setRegion:region animated:YES];
      
  • 6,添加大头针视图

大头针视图不是靠程序员使用addSubView等方式添加的,而是有系统自动添加。但程序员可以设置大头针的相关数据(经纬度,标注信息)
添加大头针时,我们需要提供大头针模型。
系统需要通过我们提供的大头针模型来获取我们想设置的大头针的相关数据。大头针模型可以是任意类,只要它遵守了MKAnnotation协议.这里使用了装饰器模式,稍后再详细讲解装饰器模式。
MKAnnotation协议中声明了两个属性(title和subtitle),大头针视图类会因为遵守了该协议而多了这两个属性的声明,和这两个属性的set&get方法的声明。我们需要在大头针视图类的.m中实现这两个属性的set&get方法。
同时,在MKAnnotation协议中"提示"我们还有一个coordinate属性需要我们自己声明,大头针视图类在声明了该属性后便可以通过给该属性赋值,来确定将大头针添加到哪个经纬度坐标

关于装饰器模式

装饰器模式也被称为装饰者模式
装饰器模式是为了给某个类扩展功能,若一个类遵守了某个装饰器协议,就可以拥有该协议赋予的功能。
例如需要归档解档时,需要遵守NSCoding协议,那这个类就可以具有归档解档的功能,以及相关的方法。
同样,如果我们需要让一个类可以为大头针视图设置数据,就需要遵守MKAnnotation,并实现相关的方法即可。
装饰器可以间接的实现“多继承”,即不需要继承自某个类就可以拥有该类的某些功能。
因此装饰器也具有解耦和的作用,因为它不需要继承指定类型

装饰器与代理的区别
1> 代理主要用于解耦和的方式传递数据 两个类耦合度很低
2> 装饰器主要用于拓展功能

装饰器模式除了使用正式协议(protocol)还可以使用非正式协议(NSObject的分类就称为非正式协议), 例如KVO。KVO的方法是写在NSObject的分类中的。
这种情况下,对象不需要遵守某个协议就可以具有此方法。因为所有类都继承自NSObject,所以NSObject分类中的方法,所有的对象都会具有。
这也是变相的实现了装饰器模式

总之,使用装饰器,只需遵守协议,实现方法,就可以了。

示例代码:

 //添加大头针模型 可以是任意类型,但是必须要遵守MKAnnotation协议HMAnnotation *anno = [HMAnnotation new];//根据点击位置设置经纬度//可以根据touch获取CGPointUITouch *touch = touches.anyObject;CGPoint point = [touch locationInView:self.mapView];//转化坐标系(iOS坐标系&经纬度进行转换)anno.coordinate = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];//anno.coordinate = CLLocationCoordinate2DMake(39.9, 116.4);[self.mapView addAnnotation:anno];
  • 7,自定义大头针视图

    • 自定义大头针视图与自定义tableViewCell极为相似,都使用了重用机制,连方法名都很类似

        - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{//过滤定位大头针,防止将“我的位置”的大头针视图换掉if ([annotation isKindOfClass:[MKUserLocation class]]) {        return nil;}static NSString *identifier = @"anno";//取MKAnnotationView *annoV = [self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];//没有,创建if (annoV == nil) {annoV = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];//设置图片annoV.image = [UIImage imageNamed:@"str"];//显示标注annoV.canShowCallout = YES;}//使用return annoV;}
      

2、使用系统地图导航

  • 使用系统地图导航的核心方法是:

      [MKMapItem openMapsWithItems:@[source, dest] launchOptions:@{MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeWalking, MKLaunchOptionsMapTypeKey: @(MKMapTypeSatellite), MKLaunchOptionsShowsTrafficKey: @YES}];
    
  • 上面方法中我们需要提供起点和终点,而方法中要求起点和终点是MKMapItem *类,并放到数组中。我们可以通过多种方式创建想要的MKMapItem *类,比如:

      //1.通过当前定位点来创建[MKMapItem mapItemForCurrentLocation];//2.通过地标对象生成MKPlacemark。 //这个通常用于地理编码方法中,在地理编码方法中可以得到placemarksMKPlacemark *pm = [[MKPlacemark alloc] initWithPlacemark:placemarks.lastObject];//创建地图项目  主要用于在系统地图上设置某个点的信息MKMapItem *dest = [[MKMapItem alloc] initWithPlacemark:pm];
    

3、自定义导航

  • 自定义导航同样需要设置起点、终点、交通方式等。流程略有不同

      //1.创建导航请求MKDirectionsRequest *request = [[MKDirectionsRequest alloc] init];//2.上面的导航请求中包含,起点、终点、交通方式等属性。只需依次进行设置即可request.source = [MKMapItem mapItemForCurrentLocation];//1.使用导航请求,创建导航对象。并且发起请求。另外还需将路线通过addOverlay绘制出来//创建导航对象MKDirections *directions = [[MKDirections alloc] initWithRequest:request];//计算路线(发起请求)[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse * _Nullable response, NSError * _Nullable error) {//取出一条路线MKRoute *route = response.routes.lastObject;//MKPolyline 地图折线类型 折线属于地图覆盖物(任意类型,遵守MKOverlay)的一种//添加地图覆盖物  还需要设置覆盖物的样式[self.mapview addOverlay:route.polyline]; //4.取出每一步的内容//for (MKRouteStep *step in route.steps) {//NSLog(@"%@", step.instructions);//}}];
    

集成第三方地图

  • 第三方地图SDK的集成可使用Cocoapods,也可手动导入,若手动导入,记得导入相关的依赖库,可根据第三方平台的操作提示,集成第三方主要看文档,遇到问题解决问题,此处不再详细介绍.谢谢.

iOS地图定位导航与大头针的简单使用相关推荐

  1. JQ----移动端h5页面通过地址调起通讯录以及高德地图、百度地图定位导航

    JQ----移动端h5页面通过地址调起通讯录以及高德地图.百度地图定位导航 通讯录: 可先加meta标签 <a href="tel:13838383838" class=&q ...

  2. iOS地图定位(Map)

    1.地图的简介 在移动互联网时代,移动app能解决用户的很多生活琐事,比如     导航:去任意陌生的地方     周边:找餐馆.找酒店.找银行.找电影院     手机软件:微信摇一摇.QQ附近的人. ...

  3. iOS地图定位小功能(上)

    讲到iOS的定位呢,首先先介绍一下定位这东西.iOS系统自带的定位服务可以实现很多需求.比如:获取当前经纬度,获取当前位置信息等等. 一.介绍 1.定位 使用CoreLocation框架     2. ...

  4. php微信地图定位导航,网页拉取微信内置地图(openLocation)详细教程 轻松实现一键导航 – 蓝洛水深...

    众所周知,我们在网页开发中,如果使用的是第三方地图,分享到微信中会非常不友好,用户只能网页导航或者通过第三方地图导航,如果我们使用的百度地图分享,则用户只能发起百度地图的导航,非常的不方便. 所以,为 ...

  5. Android安卓百度地图定位+导航+路径规划实现APP(源码+APK) 毕业设计

    百度地图实时定位+导航路径规划的实现APP 本科生毕业设计:<一种智能停车系统的设计>,成都信息工程大学,2018 使用到的技术 百度地图SDK LBS云数据管理 路径规划与导航 二维码扫 ...

  6. php微信地图定位导航,微信公众服务号下实现地图语音导航的方案

    微信公众服务号下实现地图语音导航的方案 如何在微信公众号里面实现多商家用户,店铺详情页的语音导航功能这个问题一直困惑着我. 现在有一个解决方案供大家参考. 具体步骤如下: 1.打开:http://ma ...

  7. 类似美团的iOS地图定位及调用苹果系统导航

    引入头文件 #import <CoreLocation/CoreLocation.h> #import <MapKit/MapKit.h> #import "MapV ...

  8. 室内停车场地图定位-停车场地图定位导航

    随着城市建设的高速发展,室内空间占据了人们越来越多的时间,过去几年室内导航一直不温不火的原因除了产业链.商业模式的问题外,最主要的还是用户习惯没能培养起来.事实上,单单的室内定位导航功能无法形成足够的 ...

  9. iOS 地图定位 地图

    地图 准备工作 导入MapKit框架(iOS5之后不在需要程序员自己导入) 导入主头文件**#import <MapKit/MapKit.h>** MapKit框架中所有的数据类型的前缀都 ...

最新文章

  1. 【哈利波特】Sherbert Lemon对HP的解读之六
  2. mysql删除密码代码_mysql 用户新建、受权、删除、密码修改
  3. X大佬:建议被降级降薪员工主动辞职,网友炸了
  4. 《软件需求最佳实践》阅读笔记02
  5. apache字体文件跨域_在CabloyJS中将Webpack生成的文件自动上传到阿里云OSS
  6. PHP array_diff_assoc
  7. jquery.ui.dialog 1.81在IE8中出现滚动条bug解决方法
  8. 明解c语言入门篇有用吗,各位初学者在用明解C语言(入门篇)的时候花费了多长时间?...
  9. ①万字《详解canvas api画图》小白前端入门教程(建议收藏)
  10. android 字体显示框架,资源样式 - 主题 - 《XUI - Android 原生 UI 框架》 - 书栈网 · BookStack...
  11. 我的世界开服java不是内部或外部命令_java不是内部或外部指令 也不是可运行程序 minecraft服务器...
  12. Linux如何查看显卡版本
  13. nginx反向代理指定dns
  14. 国产32层堆栈3D闪存2019年量产 2020年赶超国际
  15. php fpm设置时区,php设置时区的解决方案
  16. (二十六)Fama-French三因素模型及应用
  17. ERP系统常用SQL集锦(转, 一个网友写的,感觉有点虎头蛇尾,不过还是有价值参考)...
  18. Sigmoid函数的作用
  19. Break Continue Return( BCR ) 三者的区别
  20. matlab函数randirandint

热门文章

  1. 浙大zou jun课题组科研进展
  2. oracle 11g asm升级,Oracle 11g R1中ASM增强
  3. 机器学习之期望最大化算法(Expectation Maximization, EM)
  4. CVPR 2021 | Involution:超越卷积和自注意力的神经网络新算子
  5. 移动端APP~最新UI界面设计规范(转载)
  6. ubuntu16.04Cuda8.0安装opencv3.1
  7. 互联网摸鱼日报(2022-12-17)
  8. 计算机二级Python学习笔记(三):天天向上的力量
  9. unix 简单的命令
  10. 使用 UDP 进行消息(信令)数据传输的设计