细说地图(swift)
Posted 萧家大公子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了细说地图(swift)相关的知识,希望对你有一定的参考价值。
一 地图的基本使用
1 地图需要依赖的框架 : MapKit
2 框架基本作用 : 用于地图展示,例如大头针,路线、覆盖层展示等(着重界面展示)
3 使用步骤 :
—-> 3.1 导入头文件 : import MapKit(swift) ; #import
—-> 3.2 MapKit有一个比较重要的UI控件 :MKMapView,专门用于地图显示
4 设置地图显示类型
—-> 4.1 地图的样式可以手动设置, 在ios9.0之前有3种, iOS9.0之后增加了2种
Standard :普通地图
Satellite : 卫星云图
Hybrid : 普通 + 卫星云图
SatelliteFlyover ios9.0 3D立体
HybridFlyover ios9.0 3D立体混合
—-> 4.2 设置方式
mapView.mapType = .HybridFlyover
5 设置地图的控制项(包括 : 地图的旋转, 缩放, 移动等等操作行为都可以开启或者关闭)
—-> 5.1 设置方式 :
mapView.scrollEnabled = false //滚动
mapView.rotateEnabled = false //旋转
mapView.zoomEnabled = false //缩放 缩放和滚动默认是有的
mapView.pitchEnabled = false //3D
6 设置地图的显示项(包括 : 地图上的指南针, 比例尺, 建筑物, POI点都可以控制是否显示)
—-> 6.1 设置方式 :
if #available(iOS 9.0, *)
mapView.showsCompass = true //显示指南针
mapView.showsScale = true //显示比例尺
mapView.showsTraffic = true //显示交通
mapView.showsBuildings = true //显示建筑物
mapView.showsPointsOfInterest = true //显示兴趣点
mapView.showsUserLocation = true //显示用户
7 测试的时候常见的问题
—-> 7.1 为什么地图加载不显示? 解答 : 检查网络是否通畅
—-> 7.2 为什么地图放的太大都是格子, 禁止浏览? 解答 : 正常, 为了安全等原因, 不会看的太详细
—-> 7.3 为什么地图运行起来APP占用内存非常大? 解答 : 正常, 地图加载了很多资源
8 测试所需要的环境
—-> 8.1 加载地图数据需要联网
—-> 8.2 XCode版本根据测试选择不同版本(iOS9.0 只能使用 XCode7.0版本)
—-> 8.3 iOS系统版本根据测试选择不同版本(例如地图类型, 在iOS9.0之后才有新增)
9 地图显示用户的位置
—-> 9.1 可以设置显示用户当前所在位置, 以一个蓝点的形式呈现在地图上(注意 : 如果要显示用户位置, 在iOS8.0之后, 需要主动请求用户授权)
—-> 9.2 设置方式 : (两种)
//1. 显示用户的位置后,地图并不跟着用户的位置的改变而改变视角
mapView.showsUserLocation = true //显示用户
//2. 显示用户的位置之后,地图会跟随着用户的位置,一直让用户的位置显示在地图的中心,当时不灵活
mapView.userTrackingMode = .FollowWithHeading
—-> 9.3 两种方式呈现出来的效果 : 方式一产生效果 : 会在地图上显示一个蓝点, 标识用户所在位置; 但地图不会缩放, 而且当用户位置移动时, 地图不会跟随用户位置移动而移动; 方式二产生效果 : 会在地图上显示一个蓝点, 标识用户所在位置; 而且地图缩放到合适比例,显示用户位置, 当用户位置移动时, 地图会跟随用户位置移动而移动; 但是有时候失效.
—-> 9.4 测试的时候可能会出现的问题 : 用户位置不显示?
—-> 9.5 可能原因 : 1> 检查代码, 是否有设置显示用户位置,是否有进行请求位置授权 2> 查看模拟器是否有位置信息 3> 模拟器的问题
二 用户位置追踪
1 在storyboard中拖拽一个现实地图的UI控件
2 直接在storyboard中设置代理
3 导入框架
4 实现代理方法
5 具体代码 :
—-> 5.1 懒加载
//懒加载
private lazy var location : CLLocationManager =
let location = CLLocationManager()
if #available(iOS 8.0, *)
location.requestAlwaysAuthorization()
return location
()
—-> 5.2 地图的相关设置
override func viewDidLoad()
super.viewDidLoad()
mapView.showsBuildings = true
if #available(iOS 9.0, *)
mapView.mapType = .HybridFlyover
mapView.mapType = .Standard
mapView.showsUserLocation = true
_ = location
mapView.userTrackingMode = .FollowWithHeading
—-> 5.3 代理方法
extension ViewController : MKMapViewDelegate
//当地图获取到用户的位置的时候回调用该方法
func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation)
//MKUserLocation 大头数据模型 只要遵守了MKAnnotation就是大头针数据模型
//获取用户的大头针数据模型
userLocation.title = "肖锋"
userLocation.subtitle = "你好吗????"
//获取用户当前的中心位置
let center = userLocation.location?.coordinate
mapView.setCenterCoordinate(center!, animated: true)
//改变显示区域
let span = MKCoordinateSpanMake(0.162493481087147, 0.10857004327103)
let region = MKCoordinateRegionMake(center!, span)
mapView.setRegion(region, animated: true)
//当区域改变的时候会调用该方法
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool)
print(mapView.region.span)
6 大头针数据模型的详细解答
—-> 6.1 MKUserLocation : 被称作“大头针(数据)模型”( 其实喊什么都行,本质就是一个数据模型,只不过此模型遵循了大头针要遵循的协议(MKAnnotation))
—-> 6.2 重要属性 : location : 用户当前所在位置信息(CLLocation对象) ;title : 大头针标注要显示的标题(NSString对象) ; subtitle : 大头针标注要显示的子标题(NSString对象).
7 测试的时候可能会出现的问题
—-> 7.1 地图上的蓝点为什么不显示? 解答 : (1) 确定代码是否有误(例如, 是否显示了用户位置); (2) 确定模拟器是否设置位置 ; (3) 看下位置在哪, 是不是不在当前地图显示区域
—-> 7.2 地图跨度设置之后, 最终显示的跨度和设置数值不一致? 解答 : 因为地球的不是正方形的, 随着用户的位置移动, 会自动修正地图跨度, 保持地图不变形;
三 大头针的使用
1 大头针的理论依据 : 按照MVC原则
—-> 1.1 在地图上操作大头针,实际上是控制大头针的数据模型
—-> 1.2 添加大头针就是添加大头针数据模型
—-> 1.3 删除大头针就是删除大头针数据模型
2 需要实现如图功能(简单)
3 定义模型(必须遵守MKAnnotation协议)
—-> 3.1 创建遵守MKAnnotation的模型文件
—-> 3.2 该模型中需要的属性
import MapKit
class XFJAnnotation: NSObject , MKAnnotation
//位置坐标
var coordinate : CLLocationCoordinate2D = CLLocationCoordinate2DMake(0, 0)
//标题和子标题
var title : String?
var subtitle : String?
—-> 3.3 通过拖线的方式拿到storyboard中的map
//拿到地图
@IBOutlet weak var mapView: MKMapView!
—-> 3.4 点击屏幕获取
//点击屏幕获取
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
//获取点
let point = touches.first?.locationInView(mapView)
//将试图上的点转化为经度和纬度
let coodinate = mapView.convertPoint(point!, toCoordinateFromView: mapView)
//添加大头针
let annotation = addAnntation(coodinate, title: "肖锋", subtitle: "嘿嘿!!!")
//反地理编码获取详细信息
let location = CLLocation(latitude: coodinate.latitude, longitude: coodinate.longitude)
geoc.reverseGeocodeLocation(location) (clplc : [CLPlacemark]?, error : NSError?) -> Void in
//检查内容是否为空
guard let clplc = clplc else return
guard let clplcs = clplc.first else return
//设置大头针的标题和子标题
annotation.title = clplcs.locality
annotation.subtitle = clplcs.name
—-> 3.4 移动屏幕移除所有的大头针
//移动屏幕移除所有的大头针
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?)
//取出所有的大头针
let annotation = mapView.annotations
//移除有所的大头针
mapView.removeAnnotations(annotation)
—-> 3.5 通过一个方法创建大头针
///MARK : - 创建大头针
extension ViewController
private func addAnntation(coordinate : CLLocationCoordinate2D, title : String?, subtitle : String?) ->XFJAnnotation
//创建大头针
let annotation = XFJAnnotation()
//设置标题
annotation.title = title
annotation.subtitle = subtitle
//设置大头针的位置
annotation.coordinate = coordinate
//添加大头针
mapView.addAnnotation(annotation)
//返回大头针
return annotation
4 可能会出现的问题
—-> 4.1 反地理编码无法获取对应的数据 ? 原因 : (1) 检查是否有联网 (2) 检查代码是否有误 (3) 有时存在某些位置没有反地理编码结果, 换个点尝试, 如果都没有, 排除此原因
四 大头针的添加和删除
1 当代码执行到下面这一句的时候,会调用一个代理方法
//添加大头针
/*
当创建一个大头针数据模型添加到地图上之后,会执行对应的代理方法,在代理方法中查找对应的大头针视图
*/
mapView.addAnnotation(annotation)
—-> 1.1 会调用的代理方法(大头针的相关设置)
extension ViewController : MKMapViewDelegate
//当添加一个大头针数据模型,会调用该方法,寻找对应的大头针视图并返回,如果此处返回的是nil,代表使用系统默认的大头针
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
//创建标识
let pinID = "pinID"
//从缓存池中通过标识取出大头针视图
var pinAnntationView = mapView.dequeueReusableAnnotationViewWithIdentifier(pinID) as? MKPinAnnotationView
//判断大头针是否为空
if pinAnntationView == nil
pinAnntationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: pinID)
//设置数据模型(必须设置的)
pinAnntationView?.annotation = annotation
//运行弹框
pinAnntationView?.canShowCallout = true
//设置大头针的颜色
pinAnntationView?.pinTintColor = UIColor.redColor()
//设置大头针的下落动画
pinAnntationView?.animatesDrop = true
//拖动大头针顶视图
pinAnntationView?.draggable = true
//返回大头针视图
return pinAnntationView
—-> 1.2 拖动或者选中大头针的时候会调用(都是代理方法)
//当拖动大头针视图的时候会调用
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, didChangeDragState newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState)
print(newState.rawValue,oldState.rawValue)
//当选中大头针的时候会调用
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView)
print("选中了\\(view.annotation!.title)")
//当反选中大头针的时候回调用
func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView)
print("反选中了\\(view.annotation?.title)")
五 大头针的头像设置(左右头像设置)
1 直接在第一个代理方法中拿到大头针进行设置
//大头针的左边视图
let image = UIImage(named: "Snip20160508_1")
let imageView = UIImageView(frame: CGRectMake(0, 0, 50, 50))
imageView.image = image
pinAnntationView?.leftCalloutAccessoryView = imageView
//大头针的右边视图
let image1 = UIImage(named: "Snip20160508_2")
let imageView1 = UIImageView(frame: CGRectMake(0, 0, 60, 60))
imageView1.image = image1
pinAnntationView?.rightCalloutAccessoryView = imageView1
六 大头针的定位追踪
1 执行程序后的图片(红色标明的部分)
2 代码 : MKUserTrackingBarButtonItem(主要是这句)
override func viewDidLoad()
super.viewDidLoad()
let userTrackingItem = MKUserTrackingBarButtonItem(mapView: mapView)
navigationItem.rightBarButtonItem = userTrackingItem
_ = location
七 总结
1 这篇博客我只是简单的说明了关于地图的基本使用,具体的实现场景我得为大家写上地图在app上的具体实现,将在后续为大家介绍.(以上内容只提供给初学者学习,当然如果您有很久的开发经验,麻烦您多多赐教).
2 最后,大家如果觉得我写的博客还行的话,麻烦大家多多关注我的官方博客,谢谢!!!!
以上是关于细说地图(swift)的主要内容,如果未能解决你的问题,请参考以下文章