版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.10.14 星期日 |
前言
MapKit框架直接從您的應(yīng)用界面顯示地圖或衛(wèi)星圖像喘批,調(diào)出興趣點(diǎn)矢空,并確定地圖坐標(biāo)的地標(biāo)信息朴恳。接下來(lái)幾篇我們就一起看一下這個(gè)框架。感興趣的看下面幾篇文章毫痕。
1. MapKit框架詳細(xì)解析(一) —— 基本概覽(一)
開(kāi)始
首先看一下本文的寫(xiě)作環(huán)境
Swift 4, iOS 11, Xcode 9
MapKit是iOS設(shè)備上非常有用的API征峦,可以輕松顯示地圖迟几,繪制位置,甚至在上面繪制路線(xiàn)和其他形狀栏笆。
此更新使用來(lái)自檀香山的公共藝術(shù)品數(shù)據(jù)类腮。在本教程中,您將制作一個(gè)放大檀香山位置的應(yīng)用程序蛉加,并在地圖上繪制其中一件作品蚜枢。 您將實(shí)施pin
的標(biāo)注詳細(xì)信息按鈕以啟動(dòng)Maps
應(yīng)用程序,其中包含對(duì)藝術(shù)品的駕駛/步行路線(xiàn)针饥。 然后厂抽,您的應(yīng)用程序?qū)腍onolulu數(shù)據(jù)門(mén)戶(hù)解析JSON文件,以提取公共藝術(shù)品對(duì)象打厘,并在地圖上繪制它們修肠。
在此過(guò)程中,您將學(xué)習(xí)如何將MapKit
地圖添加到您的應(yīng)用程序户盯,縮放到特定位置嵌施,解析使用Socrata Framework的政府?dāng)?shù)據(jù),創(chuàng)建自定義地圖annotations
等等莽鸭!
打開(kāi)入門(mén)項(xiàng)目吗伤,其中包含JSON文件和一些圖像資源,但還沒(méi)有地圖硫眨!
打開(kāi)Main.storyboard
足淆。 在File Inspector
中,選中Use Safe Area Layout Guides
框礁阁。 這將阻止您設(shè)置相對(duì)于已棄用的布局指南的約束巧号,并停止deprecated
警告。
在Document Outline
中姥闭,選擇Safe Area
丹鸿,以查看其上邊緣略低于視圖的上邊緣。 從Object library
中棚品,將MapKit View
拖動(dòng)到場(chǎng)景的上角靠欢,將其頂部邊緣與視圖頂部邊緣下方的藍(lán)色虛線(xiàn)對(duì)齊,然后拖動(dòng)其右下角以與視圖的右下角相交铜跑。 使用Add New Constraints
自動(dòng)布局菜單(TIE戰(zhàn)斗機(jī)圖標(biāo))固定地圖視圖:取消選中Constrain to margins
门怪,然后將所有鄰值設(shè)置為0,并單擊Add 4 constraints
:
注意:通常情況下锅纺,您不必手動(dòng)將地圖視圖拉伸到場(chǎng)景中 - 只需使用Add New Constraints
菜單來(lái)固定其邊緣 - 但這在Xcode 9 beta中尚未使用≈揽眨現(xiàn)在Xcode 10都出來(lái)了,所以這個(gè)問(wèn)題已經(jīng)不存在了。
接下來(lái)拣帽,將此行添加到ViewController.swift
疼电,就在import UIKit
語(yǔ)句的下方:
import MapKit
Build并運(yùn)行您的項(xiàng)目,您將擁有一個(gè)完全可縮放和可平移的地圖减拭,使用Apple Maps
顯示您當(dāng)前位置的大陸蔽豺!
到目前為止這么好,嗯拧粪? 但是你不想開(kāi)始查看整個(gè)世界的地圖 - 你想放大到一個(gè)特定的區(qū)域修陡!
要控制地圖視圖,必須在ViewController.swift
中為其創(chuàng)建outlet
可霎。
在故事板中魄鸦,打開(kāi)assistant editor
:它應(yīng)該顯示ViewController.swift
。
要?jiǎng)?chuàng)建outlet
癣朗,請(qǐng)單擊Main.storyboard
中的Map View
拾因,然后按住control
- 拖動(dòng)到ViewController
類(lèi)定義內(nèi)的空間:Xcode應(yīng)提示Insert Outlet or Outlet Collection
。 釋放拖動(dòng)旷余,然后在彈出窗口中為outlet
命名為mapView
:
Xcode將一個(gè)mapView
屬性添加到ViewController
類(lèi):您將使用它來(lái)控制地圖視圖顯示的內(nèi)容绢记。
Setting Visible Area - 設(shè)置可見(jiàn)區(qū)域
切換回standard editor
,在ViewController.swift
中找到viewDidLoad()
正卧,并將以下內(nèi)容添加到方法的末尾:
// set initial location in Honolulu
let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)
您將使用它將地圖視圖的起始坐標(biāo)設(shè)置為檀香山的一個(gè)點(diǎn)蠢熄。
在告訴地圖要顯示的內(nèi)容時(shí),給出緯度和經(jīng)度足以使地圖居中炉旷,但您還必須指定要顯示的矩形區(qū)域签孔,以獲得正確的縮放級(jí)別。
將以下常量和輔助方法添加到類(lèi)中:
let regionRadius: CLLocationDistance = 1000
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius, regionRadius)
mapView.setRegion(coordinateRegion, animated: true)
}
location
參數(shù)是中心點(diǎn)窘行。 該區(qū)域?qū)⒏鶕?jù)區(qū)域的距離而具有南北和東西跨度饥追。 您將其設(shè)置為1000米:稍微超過(guò)半英里,這適用于在JSON
文件中繪制藝術(shù)品數(shù)據(jù)罐盔。
setRegion(_:animated :)
告訴mapView
顯示該區(qū)域但绕。 地圖視圖使用簡(jiǎn)潔的縮放動(dòng)畫(huà)自動(dòng)將當(dāng)前視圖轉(zhuǎn)換到所需區(qū)域,無(wú)需額外代碼翘骂!
回到viewDidLoad()
壁熄,將以下行添加到方法的末尾:
centerMapOnLocation(location: initialLocation)
您正在調(diào)用輔助方法以在啟動(dòng)時(shí)放大initialLocation
帚豪。
Build并運(yùn)行應(yīng)用程序碳竟,您將發(fā)現(xiàn)自己位于Waikiki(地名)的中心。
Obtaining Public Artworks Data - 獲取公共藝術(shù)品數(shù)據(jù)
下一步是在當(dāng)前位置周?chē)L制有趣的數(shù)據(jù)狸臣。但是在哪里可以得到這樣的東西莹桅?
那么,這取決于你當(dāng)前的位置。與許多城市一??樣诈泼,檀香山有一個(gè) Open Data Portal懂拾,可以改善公眾對(duì)政府?dāng)?shù)據(jù)的訪問(wèn)。與許多城市一??樣铐达,檀香山的數(shù)據(jù)門(mén)戶(hù)是Socrata提供支持的岖赋,這是一個(gè)開(kāi)放的數(shù)據(jù)框架,提供了一組豐富的developer tools瓮孙,用于訪問(wèn)基于Socrata
的數(shù)據(jù)唐断。完成本教程后,可以查看附近的城市是否有可以使用的備用數(shù)據(jù)集杭抠?
在本教程中脸甘,您將使用Honolulu Public Art。為了簡(jiǎn)單起見(jiàn)偏灿,我已經(jīng)從門(mén)戶(hù)網(wǎng)站下載了這些數(shù)據(jù)丹诀,并將其包含在項(xiàng)目中。
要了解此數(shù)據(jù)集中的項(xiàng)目翁垂,請(qǐng)?jiān)赬code編輯器中打開(kāi)PublicArt.json
铆遭,然后向下滾動(dòng)到第1180行(或使用?+ L表示跳轉(zhuǎn)到行),以“data”
開(kāi)頭沮峡,后跟數(shù)組數(shù)組 - 每個(gè)藝術(shù)品一個(gè)數(shù)組疚脐。對(duì)于本教程,您將僅使用每個(gè)數(shù)組中的一些屬性:藝術(shù)作品的location name, discipline, title, latitude and longitude
邢疙。例如棍弄,對(duì)于第一個(gè)數(shù)據(jù)項(xiàng):
-
location name - 地點(diǎn)名稱(chēng):
Lester McCoy Pavilion
-
discipline:
Mural
-
title - 標(biāo)題:
The Makahiki Festival – The Makai Mural
-
latitude - 緯度:
21.290824
-
longitude - 經(jīng)度:
-157.85131
在本教程的后面,您將解析此數(shù)據(jù)集以創(chuàng)建一藝術(shù)作品數(shù)組疟游,但首先呼畸,要直接跳轉(zhuǎn)到MapKit
,您只需在地圖上繪制其中一件作品颁虐。
Showing an Artwork on the Map - 在地圖上顯示藝術(shù)品
在PublicArt.json
中蛮原,跳轉(zhuǎn)或滾動(dòng)到第1233行的項(xiàng)目55:它是威基基蓋特威公園的大衛(wèi)卡拉卡瓦國(guó)王的青銅雕像。
該項(xiàng)目的屬性是:
- location name - 地點(diǎn)名稱(chēng):威基基蓋特威公園
- discipline:雕塑
- title - 標(biāo)題:大衛(wèi)卡拉卡瓦國(guó)王
-
latitude - 緯度:
21.283921
-
longitude - 經(jīng)度:
-157.831661
要在地圖視圖上顯示此內(nèi)容另绩,您必須創(chuàng)建map annotation
儒陨。 map annotation
是綁定到特定位置的小塊信息,并且通常在Apple的Maps
應(yīng)用中表示為pins
笋籽。
要?jiǎng)?chuàng)建自己的annotations
蹦漠,可以創(chuàng)建符合MKAnnotation
協(xié)議的類(lèi),將annotations
添加到地圖车海,并通知地圖應(yīng)如何顯示annotations
笛园。
1. The Artwork Class - Artwork類(lèi)
首先,在新的Swift
文件中創(chuàng)建一個(gè)Artwork
類(lèi):File \ New \ File
,選擇iOS \ Source \ Swift File
研铆,然后單擊Next
埋同。 將Save As
設(shè)置為Artwork.swift
,然后單擊Create
棵红。
在編輯器中打開(kāi)Artwork.swift
并在import Foundation
下面添加以下內(nèi)容:
import MapKit
class Artwork: NSObject, MKAnnotation {
let title: String?
let locationName: String
let discipline: String
let coordinate: CLLocationCoordinate2D
init(title: String, locationName: String, discipline: String, coordinate: CLLocationCoordinate2D) {
self.title = title
self.locationName = locationName
self.discipline = discipline
self.coordinate = coordinate
super.init()
}
var subtitle: String? {
return locationName
}
}
要采用MKAnnotation
協(xié)議凶赁,Artwork
必須是NSObject
的子類(lèi),因?yàn)?code>MKAnnotation是一個(gè)NSObjectProtocol
逆甜。
MKAnnotation
協(xié)議需要coordinate
屬性哟冬。 如果您希望annotation view
在用戶(hù)點(diǎn)擊pin
時(shí)顯示標(biāo)題和副標(biāo)題,則您的類(lèi)還需要名為title
和subtitle
的屬性忆绰。
對(duì)于Artwork
類(lèi)來(lái)說(shuō)浩峡,存儲(chǔ)名為title
和coordinate
的屬性是完全明智的,但是沒(méi)有一個(gè)PublicArt.json
屬性自然地映射到subtitle
的概念错敢。 要符合MKAnnotation
協(xié)議翰灾,您可以使subtitle
成為返回locationName
的計(jì)算屬性。
好的稚茅,所以title
, locationName
和coordinate
屬性將用于MKAnnotation
對(duì)象纸淮,但是discipline
屬性用來(lái)做什么?你會(huì)在本教程的后面找到亚享!
2. Adding an Annotation - 添加注釋
接下來(lái)咽块,您將為地圖視圖添加一個(gè)Artwork
對(duì)象,用于您要繪制的每件藝術(shù)品欺税。 目前侈沪,您只添加了一個(gè)藝術(shù)作品,因此切換到ViewController.swift
并將以下行添加到viewDidLoad()
的末尾:
// show artwork on map
let artwork = Artwork(title: "King David Kalakaua",
locationName: "Waikiki Gateway Park",
discipline: "Sculpture",
coordinate: CLLocationCoordinate2D(latitude: 21.283921, longitude: -157.831661))
mapView.addAnnotation(artwork)
在這里晚凿,您將創(chuàng)建一個(gè)新的Artwork
對(duì)象亭罪,并將其作為annotation
添加到地圖視圖中。 MKMapView
類(lèi)還有一個(gè)addAnnotations :
(復(fù)數(shù))方法歼秽,當(dāng)你有一個(gè)annotation
數(shù)組要添加到地圖視圖時(shí)应役,你將在本教程的后面使用它。
Build并運(yùn)行你的項(xiàng)目燥筷,現(xiàn)在你應(yīng)該看到King David Kalakaua
的雕像在Waikiki的入口處箩祥!
默認(rèn)annotation
標(biāo)記視圖顯示位置,標(biāo)記下方是標(biāo)題肆氓。 選擇標(biāo)記:它會(huì)變大袍祖,現(xiàn)在也會(huì)顯示副標(biāo)題:
嗯,沒(méi)關(guān)系做院,但是當(dāng)用戶(hù)點(diǎn)擊標(biāo)記時(shí)盲泛,你習(xí)慣于顯示標(biāo)注的pins
- 一個(gè)小氣泡。 為此键耕,您必須配置annotation
視圖寺滚,這是下一步。
3. Configuring the Annotation View - 配置注釋視圖
配置annotation
視圖的一種方法是實(shí)現(xiàn)地圖視圖的mapView(_:viewFor :)
代理方法屈雄。 您在此委托方法中的工作是返回MKAnnotationView
的實(shí)例村视,以作為annotation
的可視指示器呈現(xiàn)。
在這種情況下酒奶,ViewController
將成為地圖視圖的代理蚁孔。 為了避免混亂并提高可讀性,您將創(chuàng)建ViewController
類(lèi)的擴(kuò)展惋嚎。
在ViewController.swift
的底部添加以下內(nèi)容:
extension ViewController: MKMapViewDelegate {
// 1
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// 2
guard let annotation = annotation as? Artwork else { return nil }
// 3
let identifier = "marker"
var view: MKMarkerAnnotationView
// 4
if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
as? MKMarkerAnnotationView {
dequeuedView.annotation = annotation
view = dequeuedView
} else {
// 5
view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.calloutOffset = CGPoint(x: -5, y: 5)
view.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
}
return view
}
}
這是你在做的事情:
- 1)
mapView(_:viewFor :)
會(huì)為您添加到地圖的每個(gè)annotation
調(diào)用(就像使用表視圖時(shí)的tableView(_:cellForRowAt :)
一樣)杠氢,以返回每個(gè)annotation
的視圖。 - 2) 您的應(yīng)用可能會(huì)使用其他
annotation
另伍,例如用戶(hù)位置鼻百,因此請(qǐng)檢查此annotation
是否為Artwork
對(duì)象。 如果不是摆尝,則返回nil以使地圖視圖使用其默認(rèn)annotation
視圖温艇。 - 3) 要顯示標(biāo)記,可以將每個(gè)視圖創(chuàng)建為
MKMarkerAnnotationView
堕汞。 在本教程的后面勺爱,您將創(chuàng)建MKAnnotationView
對(duì)象,以顯示圖像而不是標(biāo)記讯检。 - 4) 與
tableView(_:cellForRowAt :)
類(lèi)似琐鲁,地圖視圖也會(huì)重用不再可見(jiàn)的annotation
視圖。 因此人灼,在創(chuàng)建新的annotation
視圖之前绣否,請(qǐng)檢查是否可以使用可重用的annotation
視圖。 - 5) 如果
annotation
視圖無(wú)法重用出列挡毅,則在此處創(chuàng)建新的MKMarkerAnnotationView
對(duì)象蒜撮。 它使用Artwork
類(lèi)的標(biāo)題和副標(biāo)題屬性來(lái)確定要在標(biāo)注中顯示的內(nèi)容。
注意:有一點(diǎn)需要注意的事情跪呈,由
Kalgar
建議段磨,當(dāng)你將可重復(fù)使用的annotation
出列時(shí),你給它一個(gè)標(biāo)識(shí)符耗绿。 如果您有多種annotation
樣式苹支,請(qǐng)確保每個(gè)annotation
都有唯一的標(biāo)識(shí)符,否則您可能會(huì)錯(cuò)誤地將其他類(lèi)型的標(biāo)識(shí)符出列误阻,并在您的應(yīng)用中出現(xiàn)意外行為债蜜。 同樣晴埂,它與tableView(_:cellForRowAt :)
中的單元標(biāo)識(shí)符背后的想法相同。
剩下的就是將ViewController
設(shè)置為地圖視圖的代理寻定。 您可以在Main.storyboard
中執(zhí)行此操作儒洛,但我更喜歡在代碼中執(zhí)行此操作,它更加明顯狼速。 在ViewController.swift
中琅锻,在創(chuàng)建artwork
的語(yǔ)句之前,將此行添加到viewDidLoad()
:
mapView.delegate = self
就是這樣向胡! Build并運(yùn)行項(xiàng)目恼蓬,然后點(diǎn)擊標(biāo)記以彈出標(biāo)注氣泡:
mapView(_:viewFor :)
將標(biāo)注配置為在右側(cè)包含詳細(xì)信息披露信息按鈕,但點(diǎn)擊該按鈕尚未執(zhí)行任何操作僵芹。 您可以實(shí)現(xiàn)它以顯示包含更多信息的alert彈窗处硬,或者打開(kāi)詳細(xì)視圖控制器。
這是一個(gè)很好的第三個(gè)選項(xiàng):當(dāng)用戶(hù)點(diǎn)擊信息按鈕時(shí)拇派,您的應(yīng)用程序?qū)?dòng)Maps
應(yīng)用程序郁油,完成駕駛/步行/公交路線(xiàn),從模擬用戶(hù)位置到藝術(shù)品攀痊!
Launching the Maps App - 啟動(dòng)Maps應(yīng)用程序
要提供這種出色的用戶(hù)體驗(yàn)桐腌,請(qǐng)打開(kāi)Artwork.swift
并在其他兩個(gè)下面添加此import
語(yǔ)句:
import Contacts
這將添加Contacts
框架,其中包含字典鍵常量苟径,例如CNPostalAddressStreetKey
案站,用于需要設(shè)置位置的地址,城市或州字段棘街。
接下來(lái)蟆盐,將以下輔助方法添加到類(lèi)中:
// Annotation right callout accessory opens this mapItem in Maps app
func mapItem() -> MKMapItem {
let addressDict = [CNPostalAddressStreetKey: subtitle!]
let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: addressDict)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = title
return mapItem
}
在這里,您可以從MKPlacemark
創(chuàng)建MKMapItem
遭殉。 地圖應(yīng)用程序能夠讀取此MKMapItem
石挂,并顯示正確的內(nèi)容。
接下來(lái)险污,您必須告訴MapKit
當(dāng)用戶(hù)點(diǎn)擊callout按鈕時(shí)該怎么做痹愚。 打開(kāi)ViewController.swift
,并將此方法添加到MKMapViewDelegate
擴(kuò)展:
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView,
calloutAccessoryControlTapped control: UIControl) {
let location = view.annotation as! Artwork
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
location.mapItem().openInMaps(launchOptions: launchOptions)
}
當(dāng)用戶(hù)點(diǎn)擊地圖annotation
標(biāo)記時(shí)蛔糯,標(biāo)注會(huì)顯示一個(gè)信息按鈕拯腮。如果用戶(hù)點(diǎn)擊此信息按鈕,則調(diào)用mapView(_:annotationView:calloutAccessoryControlTapped :)
方法蚁飒。
在此方法中动壤,您將獲取此點(diǎn)擊要引用的Artwork
對(duì)象,然后通過(guò)創(chuàng)建關(guān)聯(lián)的MKMapItem
并在map item
上調(diào)用openInMaps(launchOptions :)
來(lái)啟動(dòng)Maps
應(yīng)用淮逻。
請(qǐng)注意琼懊,您正在將字典傳遞給此方法阁簸。這允許您指定幾個(gè)不同的選項(xiàng);這里DirectionModeKey
設(shè)置為Driving
哼丈。這會(huì)導(dǎo)致Maps
應(yīng)用顯示從用戶(hù)當(dāng)前位置到此pin
的行車(chē)路線(xiàn)启妹。
注意:瀏覽MKMapItem documentation以查看其他啟動(dòng)選項(xiàng)字典鍵,以及
openMaps(with:launchOptions :)
方法削祈,該方法允許您傳遞MKMapItem
對(duì)象數(shù)組。
在你Build和運(yùn)行之前脑漫,你應(yīng)該搬到檀香山 - 實(shí)際上髓抑,只需將你的模擬位置設(shè)置為檀香山。在Xcode中优幸,轉(zhuǎn)到Product \ Scheme \ Edit Scheme ...
吨拍,從左側(cè)菜單中選擇Run
,然后選擇Options
選項(xiàng)卡网杆。檢查Core Location: Allow Location Simulation
羹饰,并選擇Honolulu, HI, USA
作為Default Location
。然后單擊Close
按鈕:
Build并運(yùn)行應(yīng)用程序碳却,您將看到地圖放大Waikiki
队秩,就像之前一樣。 點(diǎn)擊標(biāo)記昼浦,然后點(diǎn)擊標(biāo)注中的info
按鈕馍资,并觀看它啟動(dòng)Maps
應(yīng)用以顯示雕像的位置,并顯示其行車(chē)路線(xiàn):
注意:首次打開(kāi)
Maps
時(shí)关噪,系統(tǒng)會(huì)提示您允許Maps
訪問(wèn)您的位置(點(diǎn)按允許)鸟蟹,并顯示安全警告。
后記
本篇主要講述了基本使用簡(jiǎn)單示例使兔,感興趣的給個(gè)贊或者關(guān)注~~~