Fork me on GitHub

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

继续上一盘开始用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中添加:
    1
    2
    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showMap))
    mapView.addGestureRecognizer(tapGestureRecognizer)

另外添加方法:

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

用Geocoder转换地址到经纬度

类似下面:

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

placemarksCLPlacemark的数组。

地图标注(annotation)介绍

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

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

1
2
3
4
5
let annotation = MKPointAnnotation()
if let location = placemark.location {
annotation.coordinate = location.coordinate
mapView.addAnnotation(annotation)
}

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

RestaurantDetailViewController.swiftviewDidLoad中添加:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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!

1
- 更新`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
2
3
4
5
6
  + 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 使用地图
  • 本文作者: AndyRon
  • 发布时间: 2017年07月25日 - 00:00
  • 最后更新: 2017年09月09日 - 12:59
  • 本文链接: http://andyron.com/2017/beginning-ios-swift-15.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!