版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2018.10.14 星期日 |
前言
MapKit框架直接從您的應(yīng)用界面顯示地圖或衛(wèi)星圖像,調(diào)出興趣點,并確定地圖坐標(biāo)的地標(biāo)信息。接下來幾篇我們就一起看一下這個框架。感興趣的看下面幾篇文章。
1. MapKit框架詳細(xì)解析(一) —— 基本概覽(一)
開始
首先看一下本文的寫作環(huán)境
Swift 4, iOS 11, Xcode 9
MapKit是iOS設(shè)備上非常有用的API,可以輕松顯示地圖,繪制位置,甚至在上面繪制路線和其他形狀。
此更新使用來自檀香山的公共藝術(shù)品數(shù)據(jù)。在本教程中,您將制作一個放大檀香山位置的應(yīng)用程序,并在地圖上繪制其中一件作品。 您將實施pin
的標(biāo)注詳細(xì)信息按鈕以啟動Maps
應(yīng)用程序,其中包含對藝術(shù)品的駕駛/步行路線。 然后,您的應(yīng)用程序?qū)腍onolulu數(shù)據(jù)門戶解析JSON文件,以提取公共藝術(shù)品對象,并在地圖上繪制它們。
在此過程中,您將學(xué)習(xí)如何將MapKit
地圖添加到您的應(yīng)用程序,縮放到特定位置,解析使用Socrata Framework的政府?dāng)?shù)據(jù),創(chuàng)建自定義地圖annotations
等等!
打開入門項目,其中包含JSON文件和一些圖像資源,但還沒有地圖!
打開Main.storyboard
。 在File Inspector
中,選中Use Safe Area Layout Guides
框。 這將阻止您設(shè)置相對于已棄用的布局指南的約束,并停止deprecated
警告。
在Document Outline
中,選擇Safe Area
,以查看其上邊緣略低于視圖的上邊緣。 從Object library
中,將MapKit View
拖動到場景的上角,將其頂部邊緣與視圖頂部邊緣下方的藍(lán)色虛線對齊,然后拖動其右下角以與視圖的右下角相交。 使用Add New Constraints
自動布局菜單(TIE戰(zhàn)斗機圖標(biāo))固定地圖視圖:取消選中Constrain to margins
,然后將所有鄰值設(shè)置為0,并單擊Add 4 constraints
:
注意:通常情況下,您不必手動將地圖視圖拉伸到場景中 - 只需使用Add New Constraints
菜單來固定其邊緣 - 但這在Xcode 9 beta中尚未使用?,F(xiàn)在Xcode 10都出來了,所以這個問題已經(jīng)不存在了。
接下來,將此行添加到ViewController.swift
,就在import UIKit
語句的下方:
import MapKit
Build并運行您的項目,您將擁有一個完全可縮放和可平移的地圖,使用Apple Maps
顯示您當(dāng)前位置的大陸!
到目前為止這么好,嗯? 但是你不想開始查看整個世界的地圖 - 你想放大到一個特定的區(qū)域!
要控制地圖視圖,必須在ViewController.swift
中為其創(chuàng)建outlet
。
在故事板中,打開assistant editor
:它應(yīng)該顯示ViewController.swift
。
要創(chuàng)建outlet
,請單擊Main.storyboard
中的Map View
,然后按住control
- 拖動到ViewController
類定義內(nèi)的空間:Xcode應(yīng)提示Insert Outlet or Outlet Collection
。 釋放拖動,然后在彈出窗口中為outlet
命名為mapView
:
Xcode將一個mapView
屬性添加到ViewController
類:您將使用它來控制地圖視圖顯示的內(nèi)容。
Setting Visible Area - 設(shè)置可見區(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è)置為檀香山的一個點。
在告訴地圖要顯示的內(nèi)容時,給出緯度和經(jīng)度足以使地圖居中,但您還必須指定要顯示的矩形區(qū)域,以獲得正確的縮放級別。
將以下常量和輔助方法添加到類中:
let regionRadius: CLLocationDistance = 1000
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius, regionRadius)
mapView.setRegion(coordinateRegion, animated: true)
}
location
參數(shù)是中心點。 該區(qū)域?qū)⒏鶕?jù)區(qū)域的距離而具有南北和東西跨度。 您將其設(shè)置為1000米:稍微超過半英里,這適用于在JSON
文件中繪制藝術(shù)品數(shù)據(jù)。
setRegion(_:animated :)
告訴mapView
顯示該區(qū)域。 地圖視圖使用簡潔的縮放動畫自動將當(dāng)前視圖轉(zhuǎn)換到所需區(qū)域,無需額外代碼!
回到viewDidLoad()
,將以下行添加到方法的末尾:
centerMapOnLocation(location: initialLocation)
您正在調(diào)用輔助方法以在啟動時放大initialLocation
。
Build并運行應(yīng)用程序,您將發(fā)現(xiàn)自己位于Waikiki(地名)的中心。
Obtaining Public Artworks Data - 獲取公共藝術(shù)品數(shù)據(jù)
下一步是在當(dāng)前位置周圍繪制有趣的數(shù)據(jù)。但是在哪里可以得到這樣的東西?
那么,這取決于你當(dāng)前的位置。與許多城市一??樣,檀香山有一個 Open Data Portal,可以改善公眾對政府?dāng)?shù)據(jù)的訪問。與許多城市一??樣,檀香山的數(shù)據(jù)門戶是Socrata提供支持的,這是一個開放的數(shù)據(jù)框架,提供了一組豐富的developer tools,用于訪問基于Socrata
的數(shù)據(jù)。完成本教程后,可以查看附近的城市是否有可以使用的備用數(shù)據(jù)集?
在本教程中,您將使用Honolulu Public Art。為了簡單起見,我已經(jīng)從門戶網(wǎng)站下載了這些數(shù)據(jù),并將其包含在項目中。
要了解此數(shù)據(jù)集中的項目,請在Xcode編輯器中打開PublicArt.json
,然后向下滾動到第1180行(或使用?+ L表示跳轉(zhuǎn)到行),以“data”
開頭,后跟數(shù)組數(shù)組 - 每個藝術(shù)品一個數(shù)組。對于本教程,您將僅使用每個數(shù)組中的一些屬性:藝術(shù)作品的location name, discipline, title, latitude and longitude
。例如,對于第一個數(shù)據(jù)項:
-
location name - 地點名稱:
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)或滾動到第1233行的項目55:它是威基基蓋特威公園的大衛(wèi)卡拉卡瓦國王的青銅雕像。
該項目的屬性是:
- location name - 地點名稱:威基基蓋特威公園
- discipline:雕塑
- title - 標(biāo)題:大衛(wèi)卡拉卡瓦國王
-
latitude - 緯度:
21.283921
-
longitude - 經(jīng)度:
-157.831661
要在地圖視圖上顯示此內(nèi)容,您必須創(chuàng)建map annotation
。 map annotation
是綁定到特定位置的小塊信息,并且通常在Apple的Maps
應(yīng)用中表示為pins
。
要創(chuàng)建自己的annotations
,可以創(chuàng)建符合MKAnnotation
協(xié)議的類,將annotations
添加到地圖,并通知地圖應(yīng)如何顯示annotations
。
1. The Artwork Class - Artwork類
首先,在新的Swift
文件中創(chuàng)建一個Artwork
類:File \ New \ File
,選擇iOS \ Source \ Swift File
,然后單擊Next
。 將Save As
設(shè)置為Artwork.swift
,然后單擊Create
。
在編輯器中打開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
的子類,因為MKAnnotation
是一個NSObjectProtocol
。
MKAnnotation
協(xié)議需要coordinate
屬性。 如果您希望annotation view
在用戶點擊pin
時顯示標(biāo)題和副標(biāo)題,則您的類還需要名為title
和subtitle
的屬性。
對于Artwork
類來說,存儲名為title
和coordinate
的屬性是完全明智的,但是沒有一個PublicArt.json
屬性自然地映射到subtitle
的概念。 要符合MKAnnotation
協(xié)議,您可以使subtitle
成為返回locationName
的計算屬性。
好的,所以title
, locationName
和coordinate
屬性將用于MKAnnotation
對象,但是discipline
屬性用來做什么?你會在本教程的后面找到!
2. Adding an Annotation - 添加注釋
接下來,您將為地圖視圖添加一個Artwork
對象,用于您要繪制的每件藝術(shù)品。 目前,您只添加了一個藝術(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)建一個新的Artwork
對象,并將其作為annotation
添加到地圖視圖中。 MKMapView
類還有一個addAnnotations :
(復(fù)數(shù))方法,當(dāng)你有一個annotation
數(shù)組要添加到地圖視圖時,你將在本教程的后面使用它。
Build并運行你的項目,現(xiàn)在你應(yīng)該看到King David Kalakaua
的雕像在Waikiki的入口處!
默認(rèn)annotation
標(biāo)記視圖顯示位置,標(biāo)記下方是標(biāo)題。 選擇標(biāo)記:它會變大,現(xiàn)在也會顯示副標(biāo)題:
嗯,沒關(guān)系,但是當(dāng)用戶點擊標(biāo)記時,你習(xí)慣于顯示標(biāo)注的pins
- 一個小氣泡。 為此,您必須配置annotation
視圖,這是下一步。
3. Configuring the Annotation View - 配置注釋視圖
配置annotation
視圖的一種方法是實現(xiàn)地圖視圖的mapView(_:viewFor :)
代理方法。 您在此委托方法中的工作是返回MKAnnotationView
的實例,以作為annotation
的可視指示器呈現(xiàn)。
在這種情況下,ViewController
將成為地圖視圖的代理。 為了避免混亂并提高可讀性,您將創(chuàng)建ViewController
類的擴展。
在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 :)
會為您添加到地圖的每個annotation
調(diào)用(就像使用表視圖時的tableView(_:cellForRowAt :)
一樣),以返回每個annotation
的視圖。 - 2) 您的應(yīng)用可能會使用其他
annotation
,例如用戶位置,因此請檢查此annotation
是否為Artwork
對象。 如果不是,則返回nil以使地圖視圖使用其默認(rèn)annotation
視圖。 - 3) 要顯示標(biāo)記,可以將每個視圖創(chuàng)建為
MKMarkerAnnotationView
。 在本教程的后面,您將創(chuàng)建MKAnnotationView
對象,以顯示圖像而不是標(biāo)記。 - 4) 與
tableView(_:cellForRowAt :)
類似,地圖視圖也會重用不再可見的annotation
視圖。 因此,在創(chuàng)建新的annotation
視圖之前,請檢查是否可以使用可重用的annotation
視圖。 - 5) 如果
annotation
視圖無法重用出列,則在此處創(chuàng)建新的MKMarkerAnnotationView
對象。 它使用Artwork
類的標(biāo)題和副標(biāo)題屬性來確定要在標(biāo)注中顯示的內(nèi)容。
注意:有一點需要注意的事情,由
Kalgar
建議,當(dāng)你將可重復(fù)使用的annotation
出列時,你給它一個標(biāo)識符。 如果您有多種annotation
樣式,請確保每個annotation
都有唯一的標(biāo)識符,否則您可能會錯誤地將其他類型的標(biāo)識符出列,并在您的應(yīng)用中出現(xiàn)意外行為。 同樣,它與tableView(_:cellForRowAt :)
中的單元標(biāo)識符背后的想法相同。
剩下的就是將ViewController
設(shè)置為地圖視圖的代理。 您可以在Main.storyboard
中執(zhí)行此操作,但我更喜歡在代碼中執(zhí)行此操作,它更加明顯。 在ViewController.swift
中,在創(chuàng)建artwork
的語句之前,將此行添加到viewDidLoad()
:
mapView.delegate = self
就是這樣! Build并運行項目,然后點擊標(biāo)記以彈出標(biāo)注氣泡:
mapView(_:viewFor :)
將標(biāo)注配置為在右側(cè)包含詳細(xì)信息披露信息按鈕,但點擊該按鈕尚未執(zhí)行任何操作。 您可以實現(xiàn)它以顯示包含更多信息的alert彈窗,或者打開詳細(xì)視圖控制器。
這是一個很好的第三個選項:當(dāng)用戶點擊信息按鈕時,您的應(yīng)用程序?qū)?code>Maps應(yīng)用程序,完成駕駛/步行/公交路線,從模擬用戶位置到藝術(shù)品!
Launching the Maps App - 啟動Maps應(yīng)用程序
要提供這種出色的用戶體驗,請打開Artwork.swift
并在其他兩個下面添加此import
語句:
import Contacts
這將添加Contacts
框架,其中包含字典鍵常量,例如CNPostalAddressStreetKey
,用于需要設(shè)置位置的地址,城市或州字段。
接下來,將以下輔助方法添加到類中:
// 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)容。
接下來,您必須告訴MapKit
當(dāng)用戶點擊callout按鈕時該怎么做。 打開ViewController.swift
,并將此方法添加到MKMapViewDelegate
擴展:
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)用戶點擊地圖annotation
標(biāo)記時,標(biāo)注會顯示一個信息按鈕。如果用戶點擊此信息按鈕,則調(diào)用mapView(_:annotationView:calloutAccessoryControlTapped :)
方法。
在此方法中,您將獲取此點擊要引用的Artwork
對象,然后通過創(chuàng)建關(guān)聯(lián)的MKMapItem
并在map item
上調(diào)用openInMaps(launchOptions :)
來啟動Maps
應(yīng)用。
請注意,您正在將字典傳遞給此方法。這允許您指定幾個不同的選項;這里DirectionModeKey
設(shè)置為Driving
。這會導(dǎo)致Maps
應(yīng)用顯示從用戶當(dāng)前位置到此pin
的行車路線。
注意:瀏覽MKMapItem documentation以查看其他啟動選項字典鍵,以及
openMaps(with:launchOptions :)
方法,該方法允許您傳遞MKMapItem
對象數(shù)組。
在你Build和運行之前,你應(yīng)該搬到檀香山 - 實際上,只需將你的模擬位置設(shè)置為檀香山。在Xcode中,轉(zhuǎn)到Product \ Scheme \ Edit Scheme ...
,從左側(cè)菜單中選擇Run
,然后選擇Options
選項卡。檢查Core Location: Allow Location Simulation
,并選擇Honolulu, HI, USA
作為Default Location
。然后單擊Close
按鈕:
Build并運行應(yīng)用程序,您將看到地圖放大Waikiki
,就像之前一樣。 點擊標(biāo)記,然后點擊標(biāo)注中的info
按鈕,并觀看它啟動Maps
應(yīng)用以顯示雕像的位置,并顯示其行車路線:
注意:首次打開
Maps
時,系統(tǒng)會提示您允許Maps
訪問您的位置(點按允許),并顯示安全警告。
后記
本篇主要講述了基本使用簡單示例,感興趣的給個贊或者關(guān)注~~~