一些簡單認(rèn)識:與地圖相關(guān)的一個(gè)庫是MapKit ,MapKit是用于地圖展示的绒怨,例如大頭針,路線犬金、覆蓋層展示等(著重界面展示)
使用步驟:導(dǎo)入頭文件->創(chuàng)建一個(gè)MKMapView控件,這個(gè)控件專門用來展示地圖的.
一.地圖的基本使用
*地圖的類型
MKMapTypeStandard
普通地圖
MKMapTypeSatellite
衛(wèi)星云圖
MKMapTypeHybrid
混合模式(普通地圖覆蓋于衛(wèi)星云圖之上 )
MKMapTypeSatelliteFlyover
3D立體衛(wèi)星 (iOS9.0+)
KMapTypeHybridFlyover
3D立體混合 (iOS9.0+)
簡單示例mapView.mapType = .standard
//本文中出現(xiàn)的mapView
代表MKMapView
的一個(gè)實(shí)例對象
*地圖的操作項(xiàng)
self.mapView.zoomEnabled = ture; // 是否縮放
self.mapView.scrollEnabled = ture; // 是否滾動(dòng)
self.mapView.rotateEnabled = ture; // 是否旋轉(zhuǎn)
self.mapView.pitchEnabled = ture; // 是否顯示3DVIEW
*地圖的顯示項(xiàng)
self.mapView.showsCompass = ture; // 是否顯示指南針
self.mapView.showsScale = ture; // 是否顯示比例尺
self.mapView.showsTraffic = ture; // 是否顯示交通
self.mapView.showsBuildings = ture; // 是否顯示建筑物
簡單示例:mapView.showsPointsOfInterest = true//顯示興趣點(diǎn)
注意:顯示項(xiàng)也會(huì)受到地圖類型的影響
*地圖的其他使用
1.顯示用戶位置
self.mapView.showsUserLocation = ture
效果:該顯示方式只是在地圖上顯示一個(gè)藍(lán)點(diǎn),代表用戶的位置,地圖不會(huì)縮放, 而且當(dāng)用戶位置移動(dòng)時(shí), 地圖不會(huì)跟隨用戶位置移動(dòng)而移動(dòng)
注意:iOS8.0之后想要獲取用戶的位置,必須主動(dòng)請求用戶授權(quán).
2.設(shè)置定位的追蹤模式
mapView.userTrackingMode = .followWithHeading
效果:會(huì)在地圖上顯示一個(gè)藍(lán)點(diǎn), 標(biāo)識用戶所在位置; 而且地圖縮放到合適比例,顯示用戶位置, 當(dāng)用戶位置移動(dòng)時(shí), 地圖會(huì)跟隨用戶位置移動(dòng)而移動(dòng); 但是有時(shí)候失效(不是很靈敏);
[其他追蹤模式]
mapView.userTrackingMode = .follow//效果:不帶方向的追蹤,顯示用戶的位置,并且會(huì)跟隨用戶移動(dòng)
mapView.userTrackingMode = .none//效果:不追蹤,不顯示用戶位置
mapView的代理方法介紹:
///當(dāng)用戶的位置發(fā)生改變的時(shí)候,就會(huì)來到didUpdateuserLocation方法
///在地圖上顯示一個(gè)藍(lán)色的圓點(diǎn)來標(biāo)注用戶的位置
/// - Parameters:
/// - mapView:地圖視圖
/// - userLocation:大頭針數(shù)據(jù)模型(遵守了MKAnnotation協(xié)議的)
funcmapView(_mapView:MKMapView, didUpdate userLocation:MKUserLocation) {
//設(shè)置大頭針的標(biāo)題和子標(biāo)題
userLocation.title = "北京"
userLocation.subtitle = “天安門廣場"
// 設(shè)置地圖的中心點(diǎn)一直為用戶的位置,可以實(shí)現(xiàn)追蹤用戶的位置
// 缺陷:默認(rèn)情況下不會(huì)方法地圖的顯示區(qū)域,需要手動(dòng)放大
letcoordinate = userLocation.coordinate
mapView.setCenter(coordinate, animated:true)
//設(shè)置用戶中心點(diǎn)的區(qū)域
// center :地圖的中心點(diǎn)(經(jīng)度和緯度)
// span :區(qū)域的跨度,在地圖上東西經(jīng)各180度,總共360度,顯示的區(qū)域跨度為0-360度之間,南北緯各90度,總共180度,顯示的區(qū)域跨度為0-180度,結(jié)論:區(qū)域跨度設(shè)置的越小,那么看到的內(nèi)容就越清晰
letspan = MKCoordinateSpan(latitudeDelta:0.0067811783024751549, longitudeDelta:0.004852119671184596)
letregion = MKCoordinateRegion(center: coordinate, span: span)
mapView.setRegion(region, animated:true)
}
///當(dāng)區(qū)域改變的時(shí)候就會(huì)來到regionDidChangeAnimated animated方法
///區(qū)域改變的條件: 1.地圖中心點(diǎn)發(fā)生改變|| 2.跨度發(fā)生改變
/// - Parameters:
/// - mapView:地圖視圖
/// - animated:動(dòng)畫
funcmapView(_mapView:MKMapView, regionDidChangeAnimated animated:Bool) {
print(mapView.region.span)
}
二.地圖上的大頭針
理論支持:在地圖上操作大頭針,實(shí)際上是控制大頭針數(shù)據(jù)模型,通過修改模型,就可以控制大頭針的位置.
由于系統(tǒng)的大頭針模型是只讀的,不能進(jìn)行修改,所以我們想要操作大頭針,需要自定義大頭針模型.
自定義大頭針模型步驟:
0.導(dǎo)入MapKit模塊
1.創(chuàng)建一個(gè)類繼承NSObject
2.遵守MKAnnotation協(xié)議
3.實(shí)現(xiàn)MKAnnotation協(xié)議里面的所有方法,去掉只讀限制
varcoordinate:CLLocationCoordinate2D=CLLocationCoordinate2D(latitude:0, longitude:0)
vartitle:String?
varsubtitle:String?
點(diǎn)擊地圖,在點(diǎn)擊的位置插入大頭針的簡單實(shí)現(xiàn):
class ViewController:UIViewController{
@IBOutlet weak var mapView:MKMapView!
lazy var geoc :CLGeocoder = {
return CLGeocoder()
}()
override func touchesBegan(_touches:Set, with event:UIEvent?) {
//要求:鼠標(biāo)點(diǎn)擊在地圖哪個(gè)位置,就在對應(yīng)的位置添加一個(gè)大頭針
// 1獲取在控件上點(diǎn)擊的點(diǎn)
let point = touches.first?.location(in:mapView)
// 1.1將控件上面的點(diǎn)(CGPoint),轉(zhuǎn)為經(jīng)緯度
let coordinate = mapView.convert(point!, toCoordinateFrom:mapView)
// 1.2創(chuàng)建大頭針數(shù)據(jù)模型,并添加到地圖上
//注意:必須先設(shè)置title和subTitle的占位字
let annotation = addAnnotation(coordinate: coordinate, title:"北京", subTitle:"天安門廣場")
// 2.標(biāo)注彈框中顯示對應(yīng)的城市和街道(反地理編碼)
let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
geoc.reverseGeocodeLocation(location, completionHandler: {clpls,error in
// 2.1.判斷是否有錯(cuò)
if error != nil {
return
}
// 2.2.取出地標(biāo)對象
guard let clpl = clpls?.first else {return}
// 2.3.更新大頭針的標(biāo)題和子標(biāo)題
annotation.title= clpl.locality
annotation.subtitle= clpl.name
})
}
///添加一個(gè)自定義模型的大頭針
///
/// - Parameters:
/// - coordinate:大頭針的經(jīng)緯度
/// - title:標(biāo)題
/// - subTitle:子標(biāo)題
func addAnnotation(coordinate :CLLocationCoordinate2D, title :String, subTitle :String) ->CHAnnotation{
// 1.創(chuàng)建一個(gè)大頭針
let annotation = CHAnnotation()
// 2.確定大頭針的經(jīng)緯度(在地圖上顯示的位置)
annotation.coordinate = coordinate
// 3.設(shè)置標(biāo)題和子標(biāo)題
annotation.title = title
annotation.subtitle = subTitle
// 4.添加到地圖上
mapView.addAnnotation(annotation)
return annotation
}
補(bǔ)充大頭針的移除實(shí)現(xiàn)代碼
let annotations = mapView.annotations mapView.removeAnnotations(annotations)
自定義大頭針
理論支持:
1.如果你想要自定義大頭針視圖,必須使用MKAnnotationView或者自定義它的子類,系統(tǒng)使用的大頭針類是MKPinAnnotationView
2.大頭針也有重用機(jī)制,跟tableViewCell差不多類似的使用
mapView的代理方法介紹:
///當(dāng)在地圖上添加一個(gè)大頭針數(shù)據(jù)模型時(shí),系統(tǒng)就會(huì)自動(dòng)調(diào)用viewFor annotation代理方法,來設(shè)置對應(yīng)的大頭針視圖
///如果不實(shí)現(xiàn)該方法,或者實(shí)現(xiàn)了返回nil,則默認(rèn)使用系統(tǒng)的大頭針
///
/// - Parameters:
/// - mapView:地圖視圖
/// - annotation:大頭針數(shù)據(jù)模型
/// - Returns:返回創(chuàng)建好的大頭針視圖
func mapView(_mapView:MKMapView, viewFor annotation:MKAnnotation) ->MKAnnotationView? {
// 1.創(chuàng)建標(biāo)識
let pinID = "pinID"
// 2.通過標(biāo)識從緩存池中取出大頭針視圖
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: pinID)
// 3.判斷大頭針視圖是否存在,如果不存在則創(chuàng)建
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: pinID)
}
// 4.更新大頭針數(shù)據(jù)模型
annotationView?.annotation = annotation
// 5.設(shè)置大頭針樣子
//如果自定義了大頭針視圖,必須要指定長什么樣(否則不顯示大頭針!!!)
annotationView?.image = UIImage(named:"category_5.png")
//設(shè)置彈框(因?yàn)槟J(rèn)是不彈的)
annotationView?.canShowCallout =true
//設(shè)置大頭針的中心偏移量
// annotationView?.centerOffset = CGPoint(x: -50, y: 50)
/***********設(shè)置大頭針彈框的樣式***********/
//設(shè)置彈框的偏移量
//annotationView?.calloutOffset = CGPoint(x: 50, y: 50)
//添加彈框左邊的控件
let imageV = UIImageView(frame: CGRect(x:0, y:0, width:50, height:50))
let image = UIImage(named:"htl.jpeg")
imageV.image = image
annotationView?.leftCalloutAccessoryView = imageV
//添加彈框右邊的控件
let imageV1 = UIImageView(frame: CGRect(x:0, y:0, width:50, height:50))
let image1 = UIImage(named:"eason.jpg")
imageV1.image = image1
annotationView?.rightCalloutAccessoryView = imageV1
//添加底部的控件
annotationView?.detailCalloutAccessoryView = UISwitch()
returnannotationView
}
///當(dāng)拖拽大頭針視圖的時(shí)候開始調(diào)用annotationView viewdidChangefromOldStat方法
/// - Parameters:
/// - mapView:地圖視圖
/// - view:大頭針視圖
/// - newState:新的狀態(tài)
/// - oldState:老的狀態(tài)
func mapView(_mapView:MKMapView, annotationView view:MKAnnotationView, didChange newState:MKAnnotationViewDragState, fromOldState oldState:MKAnnotationViewDragState) {
print(newState.rawValue, oldState.rawValue)
//在這里進(jìn)行反地理編碼,顯示實(shí)際的地方名字
}
三.推薦
在開發(fā)中,一般都是集成百度地圖來進(jìn)行使用,關(guān)于百度地圖和導(dǎo)航的API的使用,百度有非常具體的說明,大家可以在網(wǎng)上搜索,按照他的指導(dǎo)來進(jìn)行配置和使用,一般都不會(huì)有什么問題的.