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

开始用Swift开发iOS 10 - 15 使用地图_第1张图片

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

开始用Swift开发iOS 10 - 15 使用地图_第2张图片

添加Map到应用中

效果图如下:

开始用Swift开发iOS 10 - 15 使用地图_第3张图片
  • Detail view的table view底部添加一个Map View。高度设置为135,取消一些属性zooming, scrolling, rotating等,使地图没有交互功能。
开始用Swift开发iOS 10 - 15 使用地图_第4张图片
开始用Swift开发iOS 10 - 15 使用地图_第5张图片
  • 删除之前去掉table view底部的代码,让底部显示。
    tableView.tableFooterView = UIView(frame: CGRect.zero)

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

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

开始用Swift开发iOS 10 - 15 使用地图_第6张图片
  • 为了能检测的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)介绍

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

开始用Swift开发iOS 10 - 15 使用地图_第7张图片

地图标注的代码一般如下,先通过地址文本生成的经纬度,规定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 改变标注针的颜色。
开始用Swift开发iOS 10 - 15 使用地图_第8张图片

地图定制

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

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

开始用Swift开发iOS 10 - 15 使用地图_第9张图片

代码

Beginning-iOS-Programming-with-Swift

说明

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

系列文章目录

  • 开始用Swift开发iOS 10 - 1 前言
  • 开始用Swift开发iOS 10 - 2 Hello World!第一个Swift APP
  • 开始用Swift开发iOS 10 - 3 介绍Auto Layout
  • 开始用Swift开发iOS 10 - 4 用Stack View设计UI
  • [开始用Swift开发iOS 10 - 5 原型的介绍]
  • 开始用Swift开发iOS 10 - 6 创建简单的Table Based App
  • 开始用Swift开发iOS 10 - 7 定制Table Views
  • 开始用Swift开发iOS 10 - 8 Table View和UIAlertController的交互
  • 开始用Swift开发iOS 10 - 9 Table Row的删除, UITableViewRowAction和UIActivityViewController的使用
  • 开始用Swift开发iOS 10 - 10 Navigation Controller的介绍和Segue
  • 开始用Swift开发iOS 10 - 11 面向对象编程介绍
  • 开始用Swift开发iOS 10 - 12 丰富Detail View和定制化Navigation Bar

你可能感兴趣的:(开始用Swift开发iOS 10 - 15 使用地图)