MapKit之MKMapView的基本认识和使用(Swift)

目的:理解MKMapView的基本使用和相关属性,并进行用户定位请求,定位成功后,显示大头针到用户当前位置,点击大头针显示大头针视图相关信息。


基本概念:

MKMapView:提供了一套可植入的地图接口,可以让我们在应用中展示地图,并对其进行相关的操作。一般来说,我们可以指定一个展示区域,放一些标记在上面,还可以加盖一些层在上面。

MKUserLocation: 遵守了MKAnnotation协议,封装地图上大头针的位置信息(位置信息CLLocation、标题title、子标题subtitle
CLLocationCoordinate2D:地理坐标(经度CLLocationDegrees longitude、纬度CLLocationDegrees latitude
CLLocationDegrees:Double类型表示对应的度数(经度、纬度)
MKCoordinateSpan:跨度(经度跨度CLLocationDegrees longitudeDelta、纬度跨度CLLocationDegrees latitudeDeltaMKCoordinateRegion:区域(中心位置CLLocationCoordinate2D center、区域跨度MKCoordinateSpan span
MKPointAnnotation: 该类定义了位于具体的点的大头针对象,我们可以直接使用该类创建系统大头针。
MKAnnotation:该类提供了大头针所需要的基本数据,如果自定义大头针,通常会遵循协议。
MKPinAnnotationView:系统自带的大头针视图,继承与MKAnnotationView。

设置MKMapViewmapViewType设置地图类型:
public enum MKMapType :UInt{
   case Standard  普通地图
   case Satellite 卫星云图
   case Hybrid    普通地图覆盖于卫星云图之上
   @available(iOS9.0, *)
   
case SatelliteFlyover
   
@available(iOS9.0, *)
   
case HybridFlyover
}

用户跟踪类型:
public enum MKUserTrackingMode :Int{
    case None    不跟踪用户的位置
    case  Follow   跟踪并在地图上显示用户的当前位置
   caseFollowWithHeading  跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转
}

代码实现部分:

class FirstViewController: UIViewController{

    

    var locationManager:CLLocationManager!

    lazy var mapView: MKMapView = {

        let mapView =MKMapView(frame: UIScreen.mainScreen().bounds)

        //用户位置追踪(用户位置追踪用于标记用户当前位置,此时会调用定位服务)

        mapView.userTrackingMode = .Follow

        //地图的显示风格,此处设置使用标准地图

        mapView.mapType = .Standard

        //地图是否可滚动,默认为true

        mapView.scrollEnabled =true

        //地图是否缩放,默认为true

        mapView.zoomEnabled =true

        //是否显示用户当前位置 ios8之后才有,默认为false

        mapView.showsUserLocation =true

        //MKMapView设置delegate

        mapView.delegate =self

        

        return mapView

    }()


    overridefunc viewDidLoad() {

        super.viewDidLoad()

        requestLocation()

        view.addSubview(self.mapView)

    }

    

    //MARK: 请求定位

    func requestLocation(){

        self.locationManager =CLLocationManager()

        ifCLLocationManager.locationServicesEnabled(){//判断定位服务是否开启

                if#available(iOS8.0, *) {//#available用在条件语句代码块中,判断不同的平台下,做不同的逻辑处理.这里表示iOS 8及其以上系统运行

                    ifself.locationManager.respondsToSelector(#selector(CLLocationManager.requestAlwaysAuthorization)) || self.locationManager.respondsToSelector(#selector(CLLocationManager.requestWhenInUseAuthorization)){

                        if(NSBundle.mainBundle().objectForInfoDictionaryKey("NSLocationAlwaysUsageDescription") != nil){

                            self.locationManager.requestAlwaysAuthorization()

                        }elseif (NSBundle.mainBundle().objectForInfoDictionaryKey("NSLocationWhenInUseUsageDescription") != nil){

                            self.locationManager.requestWhenInUseAuthorization()

                        }else{

                            print("Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");

                        }

                    }

              } else {

                print("ios8以下系统!")

            }

        }else{

           print("定位服务未开启!")

        }

    }

}


//MapView的代理

extension FirstViewController:MKMapViewDelegate {

    

    //地图的显示区域即将发生改变的时候调用

    func mapView(mapView:MKMapView, regionWillChangeAnimated animated:Bool) {

        print("当显示的区域即将改变时调用!")

    }

    

    //地图的显示区域已经发生改变的时候调用

    func mapView(mapView:MKMapView, regionDidChangeAnimated animated:Bool) {

        print("当显示的区域发生变化时调用!")

    }

    

    //地图控件即将开始加载地图数据

    func mapViewWillStartLoadingMap(mapView:MKMapView){

        print("地图控件开始加载地图数据")

    }

    

    //MKMapView加载数据完成时激发该方法

    func mapViewDidFinishLoadingMap(mapView:MKMapView){

        print("MKMapView加载数据完成时激发该方法")

    }

    

    //MKMapView加载数据失败时激发该方法如:无网络

    func mapViewDidFailLoadingMap(mapView:MKMapView, withError error:NSError){

        print("加载地图数据失败:\(error.userInfo)")

    }

    

    //MKMapView即将开始渲染地图时激发该方法

    func mapViewWillStartRenderingMap(mapView:MKMapView){

        print("MKMapView即将开始渲染地图时")

    }


    //MKMapView渲染地图完成时激发该方法

    func mapViewDidFinishRenderingMap(mapView:MKMapView, fullyRendered:Bool){

        print("MKMapView渲染地图完成时")

    }


    func mapView(mapView:MKMapView, viewForAnnotation annotation:MKAnnotation) -> MKAnnotationView?{

        let identifier ="MKPinAnnotationView"

        //从缓存池中取出可以循环利用的大头针view.

        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)

        

        if  (annotationView ==nil){

            //MKAnnotationView:可以用指定的图片作为大头针的样式,但显示的时候没有动画效果,如果没有给图片的话会什么都不显示,使用MKAnnotationView子类MKPinAnnotationView创建系统样式大头针

            annotationView =  MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)

            //显示子标题和标题

            annotationView!.canShowCallout =true

            //设置大头针描述的偏移量

            annotationView!.calloutOffset =CGPoint(x:0, y: -10)

            //设置大头针描述左边的控件

            annotationView!.leftCalloutAccessoryView =UIButton(type: .ContactAdd)

            //设置大头针描述右边的控件

            annotationView!.rightCalloutAccessoryView =UIButton(type: .DetailDisclosure)

        }

        annotationView!.annotation = annotation

        return annotationView

    }

    

    //当大头针被添加到地图上时调用

    func mapView(mapView:MKMapView, didAddAnnotationViews views: [MKAnnotationView]){

         print("添加大头针!")

    }

    

    //当点击左边或者右边附属视图的时候方法被调用

    func mapView(mapView:MKMapView, annotationView view:MKAnnotationView, calloutAccessoryControlTapped control:UIControl){

       print("calloutAccessoryControlTapped")

    }

    

    //点击选中大头针

    func mapView(mapView:MKMapView, didSelectAnnotationView view:MKAnnotationView){

       print("didSelectAnnotationView")

    }

    

    //当大头针被反选,即取消选中的时候调用,可以通过该方法改变选中大头针视图的姿态

    func mapView(mapView:MKMapView, didDeselectAnnotationView view:MKAnnotationView){

       print("didDeselectAnnotationView")

    }

   

    //showsUserLocation属性被设置为true,该方法会被调用,即将开始跟踪定位用户位置

    func mapViewWillStartLocatingUser(mapView:MKMapView){

        print("即将开始跟踪定位用户位置")

    }

    

    //showsUserLocation属性被设置为false,该方法会被调用,停止跟踪用户的位置

    func mapViewDidStopLocatingUser(mapView:MKMapView){

        print("停止跟踪用户的位置")

    }


    //当用户位置发生变化时调用,调用非常频繁,不断监测用户的当前位置,每次调用,都会把用户的最新位置(userLocation参数)传进来。

    func mapView(mapView:MKMapView, didUpdateUserLocation userLocation:MKUserLocation){

         print("didUpdateUserLocation!\(userLocation.coordinate)\(userLocation.title)\(userLocation.subtitle)")

         //在用户定位成功之后,使大头针显示用户当前的位置。注意:建议使用真机查看效果,这里会随着位置改变多次调用。

         addAnnotaionToMapView(userLocation.coordinate)

    }


    //无法定位或者用户不允许定位时,即定位失败,触发代理方法

    func mapView(mapView:MKMapView, didFailToLocateUserWithError error:NSError){

        print(error.localizedDescription)

    }

    

    //当拖动大头针的姿态改变的时候触发代理方法

    func mapView(mapView:MKMapView, annotationView view:MKAnnotationView, didChangeDragState newState:MKAnnotationViewDragState, fromOldState oldState:MKAnnotationViewDragState){

        print("didChangeDragStat")

    }

    

    //当用户的跟踪模式改变会触发代理方法

    func mapView(mapView:MKMapView, didChangeUserTrackingMode mode:MKUserTrackingMode, animated:Bool){

        print("用户的跟踪模式改变")

    }

    

    //MARK:添加大头针

    func addAnnotaionToMapView(coorinate2D:CLLocationCoordinate2D){

        

            //创建MKPointAnnotation对象——代表一个大头针

            let pointAnnotation =MKPointAnnotation()

            //设置大头针的经纬度

            pointAnnotation.coordinate = coorinate2D

            pointAnnotation.title ="Jack"

            pointAnnotation.subtitle ="hua"

            //添加大头针

            self.mapView.addAnnotation(pointAnnotation)

            

           //设置地图显示的范围,地图显示范围越小,细节越清楚

            let span =MKCoordinateSpan(latitudeDelta:0.005, longitudeDelta:0.005)

            //创建MKCoordinateRegion对象,该对象代表了地图的显示中心和显示范围。

            let region =MKCoordinateRegion(center: coorinate2D, span: span)

           //设置当前地图的显示中心和显示范围

            self.mapView.setRegion(region, animated:true)

    }

}


实现的效果图如下:


     

 






评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值