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<cllocation*>*)locations{

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

cllocation* location=locations.lastobject;

//停止定位

//[self.mgr stopupdatinglocation];

}

//实现地理编码方法

-(ibaction)geocoder{

//创建一个clgeocoder对象

clgeocoder*  geocoder=[clgeocoder  new];

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

[geocoder geocodeaddressstring:地址名  completionhandler:^(nsarray<clplacemark*>*  _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<clplacemark*>* -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<clplacemark*>*  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:(nsset<uitouch*>touches  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:(id<mkannotation>annotation){

如果发现是显示用户位置的大头针模型,就返回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<mkannotationview*>*)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





最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容