[第1章]地图:iOS简易导航

一、类介绍

MKDirections

官方文档:

这里写图片描述

解析:
1、从Apple服务得到导航服务,执行导航需要一个请求类——MKDirectionRequest(下面介绍);
2、每个实例只处理一次导航请求,如果处理多个请求,要创建多个实例;
3、不要在短时间内,请求过多次,否则触发MKErrorLoadingThrottled。

// request must not be nil.
init(request request: MKDirectionsRequest)

// 计算导航路线,在闭包handler里处理。
func calculateDirectionsWithCompletionHandler(_ completionHandler: MKDirectionsHandler)

// 闭包,response包含在Apple服务中,得到的route。
typealias MKDirectionsHandler = (MKDirectionsResponse?, NSError?) -> Void


MKDirectionRequest

注意:设置起点终点的时候,source的类型是MKMapItem。
转化示意:CLPlacemark -> MKPlacemark -> MKMapItem
实现:MKMapItem( placemark: MKPlacemark( placemark: CLPlacemark类型 ) )

// 导航的起点。
func setSource(source: MKMapItem!)

// 导航的终点。
func setDestination(destination: MKMapItem!)

// 导航方式MKDirectionsTransportType。
var transportType: MKDirectionsTransportType // Default is MKDirectionsTransportTypeAny
struct MKDirectionsTransportType : RawOptionSetType {
    // 驾驶。
    static var Automobile: MKDirectionsTransportType { get }
    // 步行。
    static var Walking: MKDirectionsTransportType { get }
    // 所有。
    static var Any: MKDirectionsTransportType { get }
}


MKMapItem

这个类可以直接跳转到苹果自动的地图,完成导航功能。(好吧…)
这里只是做这样的转换:CLPlacemark -> MKPlacemark -> MKMapItem


二、界面

这简单的界面就不用说了。

很简单的界面


三、导航

1、前言

导包、代理那些简单的就不说了,前面的文章也提到。

2、小代码

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate{

    // 地图
    @IBOutlet weak var mapView: MKMapView!
    // 起点输入框
    @IBOutlet weak var srcString: UITextField!
    // 终点输入框
    @IBOutlet weak var dstString: UITextField!
    // 开始导航按钮方法
    @IBAction func navigatingButtonClick(sender: UIButton)

    // 在geocode中,保留起点和终点各自的CLPlacemark。
    var srcPlacemark: CLPlacemark!
    var dstPlacemark: CLPlacemark!

//------------------------------------------------------------------------------   

    override func viewDidLoad() {
        super.viewDidLoad()
        self.mapView.delegate = self
    }

//------------------------------------------------------------------------------       
    // 点击事件。
    @IBAction func navigatingButtonClick(sender: UIButton) {
        // 注销第一响应。
        self.srcString.resignFirstResponder()
        self.dstString.resignFirstResponder()

        // 空输入处理。
        if srcString.text.isEmpty || dstString.text.isEmpty {
            UIAlertView(title: "Info empty", message: "Please enter completely", delegate: nil, cancelButtonTitle: "Ok").show()
            return
        }

        // 移除原来的覆盖层。
        self.mapView.removeAnnotations(self.mapView.annotations)
        self.mapView.removeOverlays(self.mapView.overlays)

        // 开始设置导航。
        self.addAnnotations(self.srcString.text)    
    }

//------------------------------------------------------------------------------   
    // 添加大头针:根据参数address(将会传入“开始”或“终点”输入框内的文本),geocode得到相对应的CLPlacemarks.
    func addAnnotations(address: String) {
        // 解析字符串,得到相对应的信息。(参考本博客相关文章)
        var geocoder = CLGeocoder()
        geocoder.geocodeAddressString(address, completionHandler: { (placemarks: [AnyObject]!, error: NSError!) -> Void in
            if error != nil && placemarks == nil{
                println(error)
                return
            }else {
                // 取第一个位置。
                let firstPlacemark = placemarks.first as! CLPlacemark

                // 添加大头针在位置上。
                var pin = MKPointAnnotation()
                pin.coordinate = firstPlacemark.location.coordinate

                // 判断起点或终点。
                if address == self.srcString.text {

                    // 保留CLPlacemark
                    self.srcPlacemark = firstPlacemark

                    // 设置大头针信息,并添加到地图。
                    pin.title = "起点"
                    pin.subtitle = self.srcPlacemark.name
                    self.mapView.addAnnotation(pin)

                    // 因为是异步,在此调用本方法,传入终点的字符串。
                    self.addAnnotations(self.dstString.text)
                }else {

                    // 同上。
                    self.dstPlacemark = firstPlacemark
                    pin.title = "终点"
                    pin.subtitle = self.dstPlacemark.name、
                    self.mapView.addAnnotation(pin)

                    // 因为是异步,在此调用画导航线路的方法。
                    self.drawRoute()
                }
            }
        })
    }

//------------------------------------------------------------------------------   
    // 画导航线路。
    func drawRoute() {
        // 创建一个请求。
        var request = MKDirectionsRequest()

        // 设置请求的起点和终点(MKMapItem类型,用getMapItemByCLPlacemark转换)。
        request.setSource(self.getMapItemByCLPlacemark(self.srcPlacemark))
        request.setDestination(self.getMapItemByCLPlacemark(self.dstPlacemark))

        // 根据request,创建一个导航类实例。
        var direction = MKDirections(request: request)

        // 计算路线。
        direction.calculateDirectionsWithCompletionHandler { (response: MKDirectionsResponse!, error: NSError!) -> Void in
            if error != nil && response == nil {
                println(error)
                return
            }else {
                // 默认只返回一条route。
                var route = response.routes.first as! MKRoute

                // 添加到地图上。
                self.mapView.addOverlay(route.polyline)
            }
        }

    }

//------------------------------------------------------------------------------       
    //  本文中,“类介绍”有提及。
    func getMapItemByCLPlacemark(mark: CLPlacemark) -> MKMapItem {
        return MKMapItem(placemark: MKPlacemark(placemark: mark))
    }

//------------------------------------------------------------------------------       
    // 用Renderer在地图上显示覆盖层。(参考本博客相关文章)
    func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
        var polylineRenderer = MKPolylineRenderer(overlay: overlay as! MKPolyline)
        polylineRenderer.strokeColor = UIColor.redColor()
        polylineRenderer.lineWidth = 5.0
        return polylineRenderer
    }
}


结果

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值