一 地图的基本使用
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
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 设置方式 : (两种)
mapView.showsUserLocation = true
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) {
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 通过一个方法创建大头针
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 {
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 执行程序后的图片(红色标明的部分)
override func viewDidLoad() {
super.viewDidLoad()
let userTrackingItem = MKUserTrackingBarButtonItem(mapView: mapView)
navigationItem.rightBarButtonItem = userTrackingItem
_ = location
}
七 总结
1 这篇博客我只是简单的说明了关于地图的基本使用,具体的实现场景我得为大家写上地图在app上的具体实现,将在后续为大家介绍.(以上内容只提供给初学者学习,当然如果您有很久的开发经验,麻烦您多多赐教).
2 最后,大家如果觉得我写的博客还行的话,麻烦大家多多关注我的官方博客,谢谢!!!!