ios地图定位大头针

corelocation框架用于地理定位

mapkit框架用于地图展示

corelocation框架中所有数据类型的前缀都是cl,corelocation中使用cllocationmanager对象来做用户定位。开始用户定位-(void)startupdatinglocation;停止用户定位-(void)stopupdatinglocation;当调用了startupdatinglocation方法后,就开始不断的定位用户的位置,中途会频繁的调用代理方法-(void)locationmanager:(cllocationmanager*)manager  didupdatelocations:(nsarray*)locations;

-(void)viewdidload{

//创建cllocationmanager对象

self.mgr=[cllocationmanager new];

//请求用户授权  从ios8开始,必须在程序中请求用户授权,除了写代码,还要配置plist列表的键值。注意适配ios7。plist的键使用期间授权nslocationwheninuseusagedescriotion永久授权nslocationalwaysusagedescription。如果写了使用期间授权和永久授权,会出现授权2次,一般来说一个应用程序只需要一种授权。大部分程序只需要使用使用期间授权即可,如果程序列表中出现3行,说明同时实现了2种授权。plist键值对的值,可以不写。建议写上原因,告诉用户为什么使用定位。ios9新增特性,临时获取后台定位权限allowsbackgroundlocationupdates=yes;如果实现了此方法还需要配置plist文件

if([uidevice  currentdevice].systemversion.floatvalue>=9.0){

self.mgr.allowsbackgroundlocationupdates=yes;

}

if([self.mgr respondstoselector:@selector(requestwheninuseauthorization)]){

//当用户使用的时候授权,在主界面运行的时候才会授权

 [self.mgr requestwheninuseauthorization];

//永久授权,不论程序有没有在主界面运行都会授权

[self.mgr requestalwaysauthorization];

}

self.mgr.delegate=self;

//调用开始定位方法

[self.mgr  startupdatinglocation];

//要像实现持续定位,我们需要对电量做些优化。距离筛选器,filter:筛选/过滤

self.mgr.distancefilter=10;

//设置精准度,iphone中的定位方式:gps/wifi/移动基站,gps24颗卫星进行通讯。我们可以降低定位的精准度,实际上降低了卫星之间的计算,以此节省电量。accuracy精准度

self.mgr.desireaccuracy=kcllocationaccuracykilometer;

//比较两个位置之间的距离 北京和西安的距离(直线距离)

cllocation* location1=[[cllocation  alloc]initwithlatitute:40  longitude:116];

cllocation* location2=[[cllocation  alloc]initwithlatitude:34.27  longitude:108.93];

cllocationdistance  distance=[location1 distancefromlocation:location2];

}

#pragma mark 代理方法

-(void)locationmanager:(cllocationmanager*)manager  didupdatelocations:(nsarray*)locations{

//cllocation位置对象,最核心的就是经纬度。cllocationcoordinate2d 2d位置坐标,经纬度

cllocation* location=locations.lastobject;

//停止定位

//[self.mgr stopupdatinglocation];

}

//实现地理编码方法

-(ibaction)geocoder{

//创建一个clgeocoder对象

clgeocoder*  geocoder=[clgeocoder  new];

//实现地理编码方法,地名转换成经纬度

[geocoder geocodeaddressstring:地址名  completionhandler:^(nsarray*  _nullable  placemarks,nserror*  _nullable  error){

if(placemarks.count==0||error){

nslog(@“解析有问题”);   return;

}

//地理编码 可能出现重名的问题,所以将来如果地标对象大于1,应该给用户一个列表选择

for(clplacemark* placemark in placemarks){

nsstring*  latitudestr=placemark.location.coordanate.latitude;

nsstring*  longitudestr=placemark.location.coordanate.longitude;

nsstring*  namestr=placemark.name;

}

}];

}

//反地理编码,将经纬度转换成地名

-(ibaction)revecegeocoder{

//创建一个geocoder对象

clgeocoder*  geocoder=[clgeocoder  new];

cllocation*  location=[[cllocation alloc]initwithlatitude:经度字符串  longitude:维度字符串];

//实现反地理编码方法

[geocoder  reversegeocodelocation:location  completionhandler:^(nsarray* -nullable  placemarks,nserror*  _nullable  error){

if(placemarks.count==0||error){ nslog(@“解析有问题”); return; }

for(clplacemark* placemark in placemarks){ }

}];

}

mapview的基本使用

显示用户位置

-(void)viewdidload{

self.mgr=[cllocationmanager new];

if([self.mgr respondstoselector:@selector(requestwheninuseauthorization)]){

//当用户使用的时候授权,在主界面运行的时候才会授权

[self.mgr requestwheninuseauthorization];

 }

//设置跟踪模式mkusertrackingmodenone,mkusertrackingmodefollow,定位mkusertrackingmodefollowwithheading,定位并显示方向

self.mapview.usertrackingmode=mkusertrackingmodefollow;

self.mapview.maptype=mkmaptypestandard;

self.mapview.delegate=self;

}

完成用户位置更新的时候调用

-(void)mapview:(mkmapview*)mapview   didupdateuserlocation:(mkuserlocation*)userlocation{

//mkuserlocation是大头针模型继承自nsobject实现了mkannotation协议

nslog(@"location:%@",userlocation.location);

}

设置地图类型

标准类型mkmaptypestandard,卫星类型mkmaptypesatellite,混合类型mkmaptypehybrid,3d卫星类型mkmaptypesatelliteflover,3d混合类型mkmaptypehybridflyover

根据用户位置显示对应的大头针信息

-(void)mapview:(mkmapview*)mapview didupdateuserlocation:(mkuserlocation*)userlocation{

//mkuserlocation是大头针模型继承自nsobject实现了mkannotation协议

nslog(@"location:%@",userlocation.location);

clgeocoder* geocoder=[geocoder new];

[geocoder reversegeocodelocation:userlocation.location   completionhandler:^(nsarray*  nullable  placemark,nerror*  nullable   error){

if(placemarks.count==0||error){return;}

}];

clplacemark*  placemark=placemarks.lastobject;

设置标题的城市信息

userlocation.title=placemark.locality;

设置子标题的详细信息

userlocation.subtitle=@"";

 }

设置用户的位置为中心点centercoordinate

设置中心点坐标

self.mapview.centercoordinate=self.mapview.userlocation.location.coordinate;

设置显示范围值越大跨度越大,显示的地图越不详细,为了跟系统的跨度保持一致,我们可以打印region的span值来获取,然后设置即可

mkcoordinatespan  span=mkcoordinate(1,1);

设置范围的属性region是一个结构体,有两个结构体构成

self.mapview.region=mkcoordinateregionmake(coordinate,span);

设置范围方法,可以设置动画

[self.mapview  setregion:mkcoordinatemake(coordinate,span)  animated:yes];

当地图显示区域发生改变后,会调用的方法

-(void)mapview:(mkmapview*)mapview  regiondidchangeanimated:(bool)animated{

nslog(@“%@,%@”,mapview.region.span.latitudedelta,mapview.region.span.longitudedelta);

}

放大和缩小地图重新设置region属性的值

ios9新特性    显示交通状况showstraffic=yes,显示建筑物状况showsbuildings=yes,显示用户位置showsuserlocation=yes,显示指南针showscompass=yes,显示比例尺showsscale=yes

添加大头针,首先要有地图mapview。Mkuserlocation大头针模型。

自定义大头针类,导入mapkit框架,继承nsobject,遵守协议mkannotation协议

创建大头针

myannotationmodel*   annotationmodel=[myannotationmodel  new];

annotationmodel.coordinate=cllocationcoordinate2dmake(39,116);

annotationmodel.title=@"北京市";

annotationmodel.subtitle=@"北京是一个迷人的地方";

添加到地图上

[self.mapview addannotation:annotationmodel];

点击添加大头针

-(void)touchbegan:(nssettouches  withevent:(uievent*)event){

cgpoint  point=[[touches  anyobject]locationinview:self.mapview];

将点转换成经纬度

cllocationcoordinate2d  coordinate=[self.mapview  convertpoint:point tocoordinatefromview:self.mapview];

myannotationmodel* annotationmodel=[myannotationmodel new]; annotationmodel.coordinate=coordinate;

annotationmodel.title=@"北京市";

 annotationmodel.subtitle=@"北京是一个迷人的地方";

 [self.mapview addannotation:annotationmodel];

}

设置大头针颜色及动画掉落,需要遵守Mkmapviewdeledate协议

只要添加大头针模型,就会来到这个方法,设置并返回对应的view

-(mkannotationview*)mapview:(mkmapview*)mapview  viewforannotaion:(idannotation){

如果发现是显示用户位置的大头针模型,就返回nil

if([annotation iskindofclass:[mkuserlocation  class]]){

return nil;

}

static  nsstring*  id=@"annoview";

mkannotationview默认Image属性没有赋值

mkpinannotationview子类是默认有view的

mkpinannotationview*  annoview=[mapview  dequeuereusableannotationviewwithidentifier:id];

if(annoview==nil){

annoview=[[mkannotationview alloc]initwithannotation:annotation  reuseidentifier:id];

pincolor只能设置red  green  purple三种颜色

//annoview.pincolor=mkpinannotationcolorgreen;

annoview.pintintcolor=[uicolor colorwithred:   green:   blue:  alpha:];

//设置动画掉落

annoview.animatesdrop=yes;

}

return  annoview;

如果返回nil,就代表用户没有自定义的需求,所有的view样式由系统提供

return nil;

}

自定义图像及掉落样式

mkannotationview* annoview=[mapview dequeuereusableannotationviewwithidentifier:id];

 if(annoview==nil){

annoview=[[mkannotationview alloc]initwithannotation:annotation reuseidentifier:id];

 pincolor只能设置red green purple三种颜色

//annoview.pincolor=mkpinannotationcolorgreen;

 annoview.pintintcolor=[uicolor colorwithred: green: blue: alpha:];

 //设置动画掉落 annoview.animatesdrop=yes;

annoview.image=[uiimage  imagenamed:@""];

也可以在大头针模型中增加一个image(icon)属性

annoview.image=[uiimage   imagenamed:(强制类型转换)annotation.icon];

设置可以点击呼之欲出之前设置的标题子标题

annoview.canshowcallout=yes;

设置左边附属视图

annoview.leftcalloutaccessoryview=[uiswitch new];

设置右边附属视图

annoview.rightcalloutaccessoryview=[uiswitch new];

ios9新增 自定义子标题

annoview.detailcalloutaccessoryview=[uiswitch new];

 }

此方法会在添加大头针的时候调用,并且,在图像出现之前调用

-(void)mapview:(mkmapview*)mapview  didaddannotationview:(nsarray*)views{

for(mkannotationview*  annoview in views){

处理显示用户位置的大头针,不要增加动画

if([annoview.annotation   iskindofclass:[mkuserlocation  class]]){

结束本次循环,进行下一次循环。

continue;

}

cgrect  endframe=annoview.frame;

annoview.frame=cgrectmake(endframe.origin.x,0,endframe.size.width,endframe.size.height);

[uiview  animatedwithduration:5  animations:^{

annoview.frame=endframe;

}];

}

}


个人github地址:zhuweigea (LaoZhu) · GitHub





你可能感兴趣的:(ios地图定位大头针)