继续上一盘开始用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
2let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(showMap))
mapView.addGestureRecognizer(tapGestureRecognizer)
另外添加方法:1
2
3func showMap() {
performSegue(withIdentifier: "showMap", sender: self)
}
用Geocoder转换地址到经纬度
类似下面:1
2
3
4
5
6
7let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString("上海东方明珠", completionHandler: {
placemarks, error in
for p in placemarks! {
print(p.location?.coordinate)
}
})
placemarks
是CLPlacemark
的数组。
地图标注(annotation)介绍
通过地址文本获得经纬度后就可在地图上标注指示,类似下面的样子:
地图标注的代码一般如下,先通过地址文本生成的经纬度,规定MKPointAnnotation
的经纬度,然后把MKPointAnnotation
添加到地图视图中即可。1
2
3
4
5let annotation = MKPointAnnotation()
if let location = placemark.location {
annotation.coordinate = location.coordinate
mapView.addAnnotation(annotation)
}
为没有交互的地图添加标注
在RestaurantDetailViewController.swift
的viewDidLoad
中添加: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
27let 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 | + 1 设置`MKPointAnnotation`一些属性 |
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》 的一篇记录