开始用Swift开发iOS 10 - 15 使用地图

作者: Andy_Ron | 来源:发表于2017-07-25 02:14 被阅读367次

    继续上一盘开始用Swift开发iOS 10 - 14 基础动画,模糊效果和Unwind Segue,这一篇使用地图。
    添加MapKit框架:

    添加Map到应用中

    效果图如下:

    • Detail view的table view底部添加一个Map View。高度设置为135,取消一些属性zooming, scrolling, rotating等,使地图没有交互功能。
    • 删除之前去掉table view底部的代码,让底部显示。
      tableView.tableFooterView = UIView(frame: CGRect.zero)

    • 添加新的视图控制器,并在其中添加Map View,调整大小为全屏。

    • control-drag从detail视图控制器到新的地图视图控制器,选择show。因为table view的头部和底部是不能选择的,所有不能从table view的底部control-drag到地图视图控制器。

    • 为了能检测的table view底部map的是否被接触,需要为地图添加UITapGestureRecognizer
      RestaurantDetailViewController.swift中引入 import MapKit;
      定义地图接口@IBOutlet var mapView: MKMapView!,并关联;
      viewDidLoad中添加:
            let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showMap))
            mapView.addGestureRecognizer(tapGestureRecognizer)
    

    另外添加方法:

    func showMap() {
        performSegue(withIdentifier: "showMap", sender: self)
    }
    

    用Geocoder转换地址到经纬度

    类似下面:

    let geoCoder = CLGeocoder()
    geoCoder.geocodeAddressString("上海东方明珠", completionHandler: {
        placemarks, error in
        for p in placemarks! {
            print(p.location?.coordinate)
        }
    })    
    

    placemarksCLPlacemark的数组。

    地图标注(annotation)介绍

    通过地址文本获得经纬度后就可在地图上标注指示,类似下面的样子:

    地图标注的代码一般如下,先通过地址文本生成的经纬度,规定MKPointAnnotation的经纬度,然后把MKPointAnnotation添加到地图视图中即可。

    let annotation = MKPointAnnotation()
    if let location = placemark.location {
        annotation.coordinate = location.coordinate
        mapView.addAnnotation(annotation)
    }
    

    为没有交互的地图添加标注

    RestaurantDetailViewController.swiftviewDidLoad中添加:

    let geoCoder = CLGeocoder()
    geoCoder.geocodeAddressString(restaurant.location, completionHandler: {
        placemarks, error in
        if error != nil {
            print(error)
            return
        }
        if let placemarks = placemarks {
            
            let placemark = placemarks[0]
            
            let annotation = MKPointAnnotation()
            
            if let location = placemark.location {
                annotation.coordinate = location.coordinate
                self.mapView.addAnnotation(annotation)
                // 规定地图显示半径 250米
                let region = MKCoordinateRegionMakeWithDistance(annotation.coordinate, 250, 250)
                self.mapView.setRegion(region, animated: false)
            }
        }
    })
    

    为全屏的地图添加标注

    • 新建一个视图控制器MapViewController,关联全屏地图控制器,引入地图框架 import MapKit
    • 第一个地图接口和restaurant变量
    @IBOutlet var mapView: MKMapView!
    var restaurant:Restaurant!
    
    • 更新viewDidLoad
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let geoCoder = CLGeocoder()
            geoCoder.geocodeAddressString(restaurant.location, completionHandler: {
                placemarks, error in
                if error != nil {
                    print(error)
                    return
                }
                if let placemarks = placemarks {
                    // Get the first placemark
                    let placemark = placemarks[0]
                    // 1
                    let annotation = MKPointAnnotation()
                    annotation.title = self.restaurant.name
                    annotation.subtitle = self.restaurant.type
                    if let location = placemark.location {
                        annotation.coordinate = location.coordinate
                        // 2
                        self.mapView.showAnnotations([annotation], animated: true)
                        self.mapView.selectAnnotation(annotation, animated: true)
                    }
                }
            })
        }
    
    • 1 设置MKPointAnnotation一些属性
    • 2 在地图展示标注。地图上课展示很多标注。selectAnnotation:方法是标注显示被选中的样式。

    在标注中添加图片

    • MapViewController实现MKMapViewDelegate协议,并在viewDidLoad中设置mapView.delegate = self
    • 添加mapView(_:viewFor:)方法,当地图每次需要annotation时调用:
        func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
            let identifier = "MyPin"
            // 1
            if annotation.isKind(of: MKUserLocation.self) {
                return nil
            }
            // 2
            var annotationView: MKPinAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView
            
            if annotationView == nil {
                annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
                annotationView?.canShowCallout = true
            }
            // 3
            let leftIconView = UIImageView(frame: CGRect(x: 0, y: 0, width: 53, height: 53))
            leftIconView.image = UIImage(named: restaurant.image)
            annotationView?.leftCalloutAccessoryView = leftIconView
            // 4
            annotationView?.pinTintColor = UIColor.orange
    
            return annotationView
        }
    
    • 1 判断是否用户当前位置。用户当前位置算是一种特殊的标注,是当前位置,就不需要另外添加标注了。
    • 2 创建MKPinAnnotationView。有点类似创建table view cell。
    • 3 在MKPinAnnotationView上添加图片。
    • 4 改变标注针的颜色。

    地图定制

        mapView.showsCompass = true
        mapView.showsScale = true
        mapView.showsTraffic = true
    

    showsCompass表示在右上角显示罗盘。
    showsScale 表示在左上角显示缩放比例尺。
    showsTraffic表示显示交通信息。

    代码

    Beginning-iOS-Programming-with-Swift

    说明

    此文是学习appcode网站出的一本书 《Beginning iOS 10 Programming with Swift》 的一篇记录

    系列文章目录

    相关文章

      网友评论

        本文标题:开始用Swift开发iOS 10 - 15 使用地图

        本文链接:https://www.haomeiwen.com/subject/rklikxtx.html