一、地图的基本使用(MapKit)
普通地图 卫星地图 混合模式(相比卫星地图多一些标识和路线) 3D立体卫星 3D立体混合代码:
import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
//设置地图的类型
mapView.mapType = .standard
//设置地图的控制项
mapView.isScrollEnabled = true
mapView.isRotateEnabled = true
mapView.isZoomEnabled = true
//设置地图的显示项
//建筑物
mapView.showsBuildings = true
//指南针
mapView.showsCompass = true
//POI兴趣点 学校,医院...
mapView.showsPointsOfInterest = true
//比例尺
mapView.showsScale = true
//交通状况
mapView.showsTraffic = true
//用户所在的位置
mapView.showsUserLocation = true;
}
}
效果图1
二、地图显示用户位置
显示用户的位置信息 地图跟随用户位置移动import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView!
lazy var locationM: CLLocationManager? = {
let locationM = CLLocationManager()
return locationM
}()
override func viewDidLoad() {
super.viewDidLoad()
//设置地图的类型
mapView.mapType = .standard
//设置地图的控制项
mapView.isScrollEnabled = true
mapView.isRotateEnabled = true
mapView.isZoomEnabled = true
//设置地图的显示项
//建筑物
mapView.showsBuildings = true
if #available(iOS 9.0, *) {
//指南针 学校,医院...
mapView.showsCompass = true
//比例尺
mapView.showsScale = true
//交通状况
mapView.showsTraffic = true
}
//POI兴趣点
mapView.showsPointsOfInterest = true
//用户所在的位置
//1.请求定位授权
if #available(iOS 8.0, *) {
locationM?.requestAlwaysAuthorization()
}
//效果:就是一个蓝点,标识用户的位置信息
//弊端:不会自动调整地图比例,另外当用户移动时地图不会跟着走。
// mapView.showsUserLocation = true;
//设置用户追踪模式
//会自动放大地图到合适的比例
//当用户位置移动时,会自动移动地图的位置信息(但不灵光)
mapView.userTrackingMode = .followWithHeading;
}
}
三、模拟追踪显示用户位置
1、显示用户位置的蓝点
代码:
import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView!
//懒加载
lazy var locationManager: CLLocationManager = {
let locationManager = CLLocationManager()
return locationManager
}()
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
//0. 请求用户授权
if #available(iOS 8.0, *) {
locationManager.requestAlwaysAuthorization()
}
//1.显示用户位置的蓝点
mapView.showsUserLocation = true
}
}
extension ViewController: MKMapViewDelegate{
/**获取用户位置信息
* mapView 地图
* userLocation 大头针数据模型
*/
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
//MKUserLocation: "大头针数据模型",其实叫什么都可以,只不过这个类遵循了大头针数据模型必须遵循的一个协议MKAnnotation
//验证当前的userLocation,对应的大头针视图就是我们看到的蓝点
userLocation.title = "大哥"
userLocation.subtitle = "打你"
}
}
2、调整地图中心
效果:只是调整地图的显示中心,但不会自动放大地图extension ViewController: MKMapViewDelegate{
/**获取用户位置信息
* mapView 地图
* userLocation 大头针数据模型
*/
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
//MKUserLocation: "大头针数据模型",其实叫什么都可以,只不过这个类遵循了大头针数据模型必须遵循的一个协议MKAnnotation
//验证当前的userLocation,对应的大头针视图就是我们看到的蓝点
//coordinate: CLLocationCoordinate2D确定当前大头针插在哪个位置
userLocation.title = "大哥"
userLocation.subtitle = "打你"
print("location:\(userLocation.coordinate)")
//2.调整地图中心(显示用户的位置信息后,通过控制地图的中心坐标来不断跟随用户位置)
//效果:只是调整地图的显示中心,但不会自动放大地图
mapView.setCenter(userLocation.coordinate, animated: true)
}
}
3、设置地图显示区域
3步都完成后的效果图import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView!
//懒加载
lazy var locationManager: CLLocationManager = {
let locationManager = CLLocationManager()
return locationManager
}()
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
//0. 请求用户授权
if #available(iOS 8.0, *) {
locationManager.requestAlwaysAuthorization()
}
//1.显示用户位置的蓝点
mapView.showsUserLocation = true
}
}
extension ViewController: MKMapViewDelegate{
/**获取用户位置信息
* mapView 地图
* userLocation 大头针数据模型
*/
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
//MKUserLocation: "大头针数据模型",其实叫什么都可以,只不过这个类遵循了大头针数据模型必须遵循的一个协议MKAnnotation
//验证当前的userLocation,对应的大头针视图就是我们看到的蓝点
//coordinate: CLLocationCoordinate2D确定当前大头针插在哪个位置
userLocation.title = "大哥"
userLocation.subtitle = "打你"
print("location:\(userLocation.coordinate)")
//2.调整地图中心(显示用户的位置信息后,通过控制地图的中心坐标来不断跟随用户位置)
//效果:只是调整地图的显示中心,但不会自动放大地图
mapView.setCenter(userLocation.coordinate, animated: true)
//3、设置地图显示区域
//区域region(包括中心(center)和跨度(span))
//跨度:1.经度跨度(地图视图的宽所占据的经度) 2.纬度跨度(地图视图的高所占据的纬度)
//经纬度跨度越小,我们看到的地图越详细
let center: CLLocationCoordinate2D = (userLocation.location?.coordinate)!
let span: MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: 0.012700175462356356, longitudeDelta: 0.0083434505961861305)
let region: MKCoordinateRegion = MKCoordinateRegion(center: center, span: span)
mapView.setRegion(region, animated: true)
}
//区域改变时调用
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
//在这个方法里我们手动的放大区域,来寻找合适的跨度设置到上一个方法中的经纬度跨度
print(mapView.region.span)
}
}
四、大头针的基本使用
1、增加一个大头针数据模型
增加一个大头针数据模型2、点击屏幕view时移除mapView所有大头针
点击屏幕view时移除mapView所有大头针代码:
---------------------------自定义一个大头针数据模型---------------------------
import UIKit
import MapKit
class WXAnnotation: NSObject,MKAnnotation {
//去掉大头针在地图上的位置
var coordinate: CLLocationCoordinate2D
//点击大头针弹框标题
var title: String?
//点击大头针弹框子标题
var subtitle: String?
init(coordinate: CLLocationCoordinate2D,title: String?,subtitle: String?){
self.coordinate = coordinate
self.title = title
self.subtitle = subtitle
}
}
----------------------------ViewController.swift--------------------------
import UIKit
import MapKit
//MVC
//操作大头针视图,实际就是操作的大头针数据模型
//添加一个大头针视图,就是添加一个大头针数据模型
//删除一个大头针视图,就是删除一个大头针数据模型
class ViewController: UIViewController {
lazy var locationM: CLLocationManager = {
let locationM = CLLocationManager()
return locationM
}()
@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
//请求定位授权
if #available(iOS 8.0, *) {
locationM.requestAlwaysAuthorization()
}
mapView.delegate = self
// mapView.showsUserLocation = true
mapView.userTrackingMode = .followWithHeading;
}
}
extension ViewController: MKMapViewDelegate {
/**获取用户位置信息
* mapView 地图视图
* userLocation 大头针数据模型
*/
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
//1.创建一个大头针数据模型
let annotation:WXAnnotation = WXAnnotation(coordinate: (userLocation.location?.coordinate)!, title: "你好", subtitle: "hello world")
//2.添加一个大头针数据模型
mapView.addAnnotation(annotation)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//3.移除大头针数据模型(可以移除一个或所有大头针)
mapView.removeAnnotations(mapView.annotations)
}
}
3、大头针的使用场景
点击mapView时添加一个大头针,弹框时显示城市名称
点击mapView时添加一个大头针,弹框时显示城市名称import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView!
lazy var locationM: CLLocationManager = {
let locationM = CLLocationManager()
return locationM
}()
//地理编码和反地理编码的类
lazy var geoCoder:CLGeocoder = {
let geoCoder = CLGeocoder()
return geoCoder
}()
override func viewDidLoad() {
super.viewDidLoad()
//请求定位授权
if #available(iOS 8.0, *) {
locationM.requestAlwaysAuthorization()
}
mapView.delegate = self
// mapView.showsUserLocation = true
mapView.userTrackingMode = .followWithHeading;
}
}
extension ViewController: MKMapViewDelegate {
/**获取用户位置信息
* mapView 地图视图
* userLocation 大头针数据模型
*/
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
//1.创建一个大头针数据模型
let annotation:WXAnnotation = WXAnnotation(coordinate: (userLocation.location?.coordinate)!, title: "你好", subtitle: "hello world")
//2.添加一个大头针数据模型
mapView.addAnnotation(annotation)
}
//点击地图添加大头针
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1.获取当前手指点击对应的经纬度
//触摸点在mapView上的位置,以mapView左上角为坐标原点
let point = touches.first?.location(in: mapView)
//从哪个视图上转换点坐标->经纬度坐标
let coordinate = mapView.convert(point!, toCoordinateFrom: mapView)
//2、调用添加大头针的方法
let annotation = addAnnotation(coordinate: coordinate, title: "nihao", subTitle: "shijie")
let location: CLLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
//反地理编码
geoCoder.reverseGeocodeLocation(location) {(pls, error) in
if error == nil{
let pl = pls?.first
annotation.title = pl?.locality
annotation.subtitle = pl?.name
}
}
}
func addAnnotation(coordinate:CLLocationCoordinate2D,title: String? ,subTitle: String?) -> WXAnnotation {
//1.创建一个大头针数据模型
let annotation: WXAnnotation = WXAnnotation(coordinate: coordinate, title: title, subtitle: subTitle)
//2.添加一个大头针数据模型
mapView.addAnnotation(annotation)
return annotation
}
}
4、自定义大头针,模拟系统实现
自定义大头针,模拟系统实现import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView!
lazy var locationM: CLLocationManager = {
let locationM = CLLocationManager()
return locationM
}()
//地理编码和反地理编码的类
lazy var geoCoder:CLGeocoder = {
let geoCoder = CLGeocoder()
return geoCoder
}()
override func viewDidLoad() {
super.viewDidLoad()
//请求定位授权
if #available(iOS 8.0, *) {
locationM.requestAlwaysAuthorization()
}
mapView.delegate = self
mapView.showsUserLocation = true
// mapView.userTrackingMode = .followWithHeading;
}
//点击地图添加大头针
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1.获取当前手指点击对应的经纬度
//触摸点在mapView上的位置,以mapView左上角为坐标原点
let point = touches.first?.location(in: mapView)
//从哪个视图上转换点坐标->经纬度坐标
let coordinate = mapView.convert(point!, toCoordinateFrom: mapView)
//2、调用添加大头针的方法
let annotation = addAnnotation(coordinate: coordinate, title: "nihao", subTitle: "shijie")
let location: CLLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
//反地理编码
geoCoder.reverseGeocodeLocation(location) {(pls, error) in
if error == nil{
let pl = pls?.first
annotation.title = pl?.locality
annotation.subtitle = pl?.name
}
}
}
func addAnnotation(coordinate:CLLocationCoordinate2D,title: String? ,subTitle: String?) -> WXAnnotation {
//1.创建一个大头针数据模型
let annotation: WXAnnotation = WXAnnotation(coordinate: coordinate, title: title, subtitle: subTitle)
//2.添加一个大头针数据模型
mapView.addAnnotation(annotation)
return annotation
}
}
extension ViewController: MKMapViewDelegate {
/**获取用户位置信息
* mapView 地图视图
* userLocation 大头针数据模型
*/
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
//1.创建一个大头针数据模型
let annotation:WXAnnotation = WXAnnotation(coordinate: (userLocation.location?.coordinate)!, title: "你好", subtitle: "hello world")
//2.添加一个大头针数据模型
mapView.addAnnotation(annotation)
}
/**模型
*如果我们添加一个大头针数据模型,系统会调用一个方法查找对应的大头针视图显示到地图上;如果这个方法没有实现或者返回为nil,那么系统就会使用默认的大头针视图显示到地图上
* mapView 地图视图
* annotation 大头针数据模型
* 返回值是大头针视图
*/
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
//模拟系统的实现方案
//MKPinAnnotationView 系统大头针视图对应的类
//大头针其实是有一个“循环利用机制”
//1.先从缓存池里获取大头针视图
let identifier = "pin"
var annotationView: MKPinAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView
//2.如果没有获取到,自己创建
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
}
//3.对大头针视图进行赋值(这步操作非常重要)
annotationView?.annotation = annotation
//3.1.设置大头针参数
if #available(iOS 9.0, *) {
annotationView?.pinTintColor = UIColor.red
}
//3.2.设置弹框
annotationView?.canShowCallout = true
//3.3.设置下落动画
annotationView?.animatesDrop = true
//4.返回大头针视图
return annotationView
}
}
5、自定义大头针和弹框
import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView!
lazy var locationM: CLLocationManager = {
let locationM = CLLocationManager()
return locationM
}()
//地理编码和反地理编码的类
lazy var geoCoder:CLGeocoder = {
let geoCoder = CLGeocoder()
return geoCoder
}()
override func viewDidLoad() {
super.viewDidLoad()
//请求定位授权
if #available(iOS 8.0, *) {
locationM.requestAlwaysAuthorization()
}
mapView.delegate = self
// mapView.showsUserLocation = true
mapView.userTrackingMode = .followWithHeading;
}
//点击地图添加大头针
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1.获取当前手指点击对应的经纬度
//触摸点在mapView上的位置,以mapView左上角为坐标原点
let point = touches.first?.location(in: mapView)
//从哪个视图上转换点坐标->经纬度坐标
let coordinate = mapView.convert(point!, toCoordinateFrom: mapView)
//2、调用添加大头针的方法
let annotation = addAnnotation(coordinate: coordinate, title: "nihao", subTitle: "shijie")
let location: CLLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
//反地理编码
geoCoder.reverseGeocodeLocation(location) {(pls, error) in
if error == nil{
let pl = pls?.first
annotation.title = pl?.locality
annotation.subtitle = pl?.name
}
}
}
func addAnnotation(coordinate:CLLocationCoordinate2D,title: String? ,subTitle: String?) -> WXAnnotation {
//1.创建一个大头针数据模型
let annotation: WXAnnotation = WXAnnotation(coordinate: coordinate, title: title, subtitle: subTitle)
//2.添加一个大头针数据模型
mapView.addAnnotation(annotation)
return annotation
}
}
extension ViewController: MKMapViewDelegate {
/**获取用户位置信息
* mapView 地图视图
* userLocation 大头针数据模型
*/
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
//1.创建一个大头针数据模型
let annotation:WXAnnotation = WXAnnotation(coordinate: (userLocation.location?.coordinate)!, title: "你好", subtitle: "hello world")
//2.添加一个大头针数据模型
mapView.addAnnotation(annotation)
}
/**模型
*如果我们添加一个大头针数据模型,系统会调用一个方法查找对应的大头针视图显示到地图上;如果这个方法没有实现或者返回为nil,那么系统就会使用默认的大头针视图显示到地图上
* mapView 地图视图
* annotation 大头针数据模型
* 返回值是大头针视图
*/
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
//1.如果想要自定义大头针视图,要不使用MKAnnotationView,要不就是使用自定义的子类
//2.如果使用了自定义视图,那么几乎所有的东西都需要我们自己设置
let identifier = "pin"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil{
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier)
}
annotationView?.annotation = annotation
//1.设置大头针视图的图片
annotationView?.image = UIImage(named: "category_2.png")
//2.设置弹框
annotationView?.canShowCallout = true
//3.设置大头针视图的偏移量
annotationView?.centerOffset = CGPoint(x: 10, y: 10)
//4.控制弹框的偏移量
annotationView?.calloutOffset = CGPoint(x: -20, y: 20)
//5.设置弹框的左侧内容(左侧ImageView和右侧ImageView要单独设置,不能共用一个)
let imageV1: UIImageView = UIImageView(frame:CGRect(x: 0, y: 0, width: 100, height: 100))
imageV1.image = UIImage(named: "htl.jpeg")
annotationView?.leftCalloutAccessoryView = imageV1
//6.设置弹框的右侧内容
let imageV2: UIImageView = UIImageView(frame:CGRect(x: 0, y: 0, width: 100, height: 100))
imageV2.image = UIImage(named: "huba.jpeg")
annotationView?.rightCalloutAccessoryView = imageV2
//7.设置详情视图
if #available(iOS 9.0, *) {
annotationView?.detailCalloutAccessoryView = UISwitch()
}
return annotationView
}
}
材料
网友评论