细说地图(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)的主要内容,如果未能解决你的问题,请参考以下文章

Swift 中的 MapKit

百度地图整体封装大头针

在地图上重复引脚注释

放置图钉并从用户在地图上点击的位置获取地址

利用高德地图完成用户地图选址,包括搜索位置和标签固定居中

地图篇-04.添加/删除大头针