在 iOS 應用程式中加入地圖 (Swift)

1. 事前準備

本程式碼研究室會說明如何開始使用 Google 地圖平台,以 Swift 建構 iOS 應用程式。您將建構 iOS 應用程式,並執行下列操作:

  • 載入 Maps SDK for iOS 和 Maps SDK for iOS 公用程式庫。
  • 顯示以澳洲雪梨為中心的地圖。
  • 顯示雪梨周圍 100 個點的自訂標記。
  • 實作標記叢集。
  • 啟用使用者互動功能,在輕觸標記時,重新置中並在地圖上繪製圓圈。

iOS 應用程式中的地圖和標記

必要條件

  • 具備 Swift 和 iOS 開發作業的基本知識。

學習內容

  • 載入 Maps SDK for iOS 和 Google Maps SDK for iOS 公用程式庫。
  • 載入地圖。
  • 使用標記、自訂標記和標記叢集。
  • 使用 Maps SDK for iOS 事件系統支援使用者互動。
  • 以程式輔助方式控制地圖攝影機。
  • 在地圖上繪圖。

軟硬體需求

如要完成本程式碼研究室,您需要下列帳戶、服務和工具:

  • Xcode 12.0 以上版本,目標 SDK 為 12.0 以上版本。
  • 已安裝 Cocoapods。
  • 已啟用計費功能的 Google Cloud Platform 帳戶 (請參閱下一個步驟)。
  • 在 Cloud 控制台中啟用 Maps SDK for iOS 的專案 (請參閱下一個步驟)。

2. 做好準備

如要完成下方的啟用步驟,請啟用 Maps SDK for iOS。

設定 Google 地圖平台

如果您尚未建立 Google Cloud Platform 帳戶,以及啟用計費功能的專案,請參閱「開始使用 Google 地圖平台」指南,建立帳單帳戶和專案。

  1. 在 Cloud 控制台中,按一下專案下拉式選單,然後選取要用於本程式碼研究室的專案。

  1. 在 Google Cloud Marketplace 中,啟用本程式碼研究室所需的 Google 地圖平台 API 和 SDK。如要瞭解如何操作,請觀看這部影片或參閱這份說明文件。
  2. 在 Cloud Console 的「憑證」頁面中產生 API 金鑰。你可以按照這部影片或這份文件中的步驟操作。所有 Google 地圖平台要求都需要 API 金鑰。

快速入門導覽課程

為協助您盡快上手,我們提供一些範例程式碼,方便您跟著本程式碼研究室的說明操作。

  1. 如果已安裝 git,請複製存放區。
git clone https://github.com/googlemaps/codelab-maps-platform-101-swift.git

或者,按一下「給我程式碼」下載原始碼。

  1. 下載程式碼後,開啟 /starter 目錄中的 StarterApp 專案。這個專案包含完成程式碼研究室所需的基本檔案結構。所有工作所需項目都位於 /starter/StarterApp 目錄中。

如要查看完整的解決方案程式碼,請查看 /solution/SolutionApp 目錄中的完整程式碼。

3. 安裝 Maps SDK for iOS

使用 Maps SDK for iOS 的第一步是安裝必要依附元件。這個程序分為兩個步驟:從 Cocoapods 依附元件管理工具安裝 Maps SDK for iOS 和 Maps SDK for iOS 公用程式庫,然後向 SDK 提供 API 金鑰。

  1. 將 Maps SDK for iOS 和 Maps SDK for iOS 公用程式庫新增至 Podfile。

本程式碼研究室會使用 Maps SDK for iOS (提供所有 Google 地圖核心功能) 和 Maps iOS 公用程式庫 (提供各種公用程式來豐富地圖內容,包括標記叢集)。

首先,在 Xcode (或您偏好的文字編輯器) 中開啟 Podfile,並更新檔案,在註解 # Pods for StarterApp 下方加入 Maps SDK for iOS 和公用程式庫依附元件:

pod 'GoogleMaps', '6.1.0'
pod 'Google-Maps-iOS-Utils', '3.4.0'

請參閱 Maps SDK for iOS 版本說明文件,瞭解最新版 SDK 和維護指南。

您的 Podfile 應如下所示:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'

target 'StarterApp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for StarterApp
  pod 'GoogleMaps', '6.1.0'
  pod 'Google-Maps-iOS-Utils', '3.4.0'
end
  1. 安裝 Maps SDK for iOS 和 Maps SDK for iOS 公用程式庫 Pod。

如要安裝依附元件,請透過指令列在 /starter 目錄中執行 pod install。Cocoapods 會自動下載依附元件並建立 StarterApp.xcworkspace。

  1. 安裝依附元件後,請從 /starter 目錄執行 open StarterApp.xcworkspace,在 Xcode 中開啟檔案,然後按下 Command+R,在 iPhone 模擬器中執行應用程式。如果一切設定正確,模擬器就會啟動並顯示黑畫面。別擔心,您尚未建構任何內容,因此這是正常現象!
  2. 在 AppDelegate.swift 中匯入 SDK。

依附元件安裝完成後,請將 API 金鑰提供給 SDK。第一步是匯入 Maps SDK for iOS 做為依附元件,方法是在 import UIKit 匯入陳述式下方加入下列內容:

import GoogleMaps
  1. 在 application: didFinishLaunchingWithOptions: 中對 GMSServices 呼叫 provideAPIKey,將 API 金鑰傳遞至 iOS SDK
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // Override point for customization after application launch.
    GMSServices.provideAPIKey("YOUR_API_KEY")

    return true
  }

更新後的 AppDelegate.swift 檔案應如下所示:

import UIKit
import GoogleMaps

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // Override point for customization after application launch.
    GMSServices.provideAPIKey("YOUR_API_KEY")

    return true
  }

}

將 YOUR_API_KEY 替換為您在 Cloud 控制台中建立的 API 金鑰。

安裝依附元件並提供 API 金鑰後,您就可以開始呼叫 Maps SDK for iOS。

4. 顯示地圖

現在要顯示第一張地圖了!

Maps SDK for iOS 最常用的部分是 GMSMapView 類別,其中提供許多方法,可供您建立及操控地圖例項。方法如下:

  1. 開啟 ViewController.swift。

您將在本程式碼研究室的其餘部分,請注意,檢視畫面控制器的 loadView和 viewDidLoad 生命週期事件已為您存根化。

  1. 在檔案頂端加入下列程式碼,匯入 Maps SDK for iOS:
import GoogleMaps
  1. 宣告 ViewController 例項變數,儲存 GMSMapView。

GMSMapView 執行個體是您在本程式碼研究室中使用的主要物件,您將從各種檢視區塊控制器生命週期方法中參照並對其採取行動。如要提供這項資訊,請更新 ViewController 的實作方式,宣告執行個體變數來儲存這項資訊:

class ViewController: UIViewController {

  private var mapView: GMSMapView!

  ...
}
  1. 在 loadView 中,建立 GMSCameraPosition 的執行個體。

GMSCameraPosition 會定義地圖的中心位置和顯示的縮放等級。這段程式碼會呼叫 cameraWithLatitude:longitude:zoom: 方法,將地圖中心設在澳洲雪梨 (緯度為 -33.86,經度為 151.20),並將縮放等級設為 12:

let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 12)
  1. 在 loadView 中,建立 GMSMapView 的例項,將地圖例項化。

如要建立新的地圖例項,請呼叫 GMSMapView(frame: CGRect, camera: GMSCameraPosition)。請注意,影格設為 CGRect.zero,這是 iOS CGGeometry 程式庫的全球變數,用於指定寬度為 0、高度為 0 的影格,位於檢視畫面控制器內的 (0,0) 位置。攝影機會設為您剛建立的攝影機位置。

接著,如要顯示地圖,請將檢視控制器的根層級檢視區塊設為 mapView,這樣地圖就會以全螢幕顯示。

    mapView = GMSMapView(frame: .zero, camera: camera)
    self.view = mapView
  1. 將 GMSMapViewDelegate 設為檢視畫面控制器。

實作後,地圖檢視區塊委派可讓您處理 GMSMapView 執行個體上的使用者互動事件,稍後會用到。

首先,請更新 ViewController 的介面,以符合 GMSMapViewDelegate: 的通訊協定

class ViewController: UIViewController, GMSMapViewDelegate

接著,在 loadView 函式中加入下列程式碼,將 GMSMapViewDelegate 設為 ViewController。

    mapView.delegate = self

現在請在 iOS 模擬器中重新載入應用程式 (Command+R),地圖應會如以下螢幕截圖所示:

顯示 Google 地圖的 iOS 應用程式

圖 1. 顯示 Google 地圖的 iOS 應用程式。

回顧一下,在這個步驟中,您建立了 GMSMapView 的執行個體,顯示以澳洲雪梨市為中心的地圖。

您的 ViewController.swift 檔案現在看起來應像這樣:

import UIKit
import GoogleMaps

class ViewController: UIViewController, GMSMapViewDelegate {

  private var mapView: GMSMapView!

  override func loadView() {

    // Load the map at set latitude/longitude and zoom level
    let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 11)

    mapView = GMSMapView(frame: .zero, camera: camera)
    self.view = mapView
    mapView.delegate = self
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
  }

}

5. 設定地圖樣式 (選用)

您可以使用雲端式地圖樣式設定自訂地圖樣式。

建立地圖 ID

如果尚未建立地圖 ID 並與地圖樣式建立關聯,請參閱「地圖 ID」指南,完成下列步驟:

  1. 建立地圖 ID。
  2. 將地圖 ID 與地圖樣式建立關聯。

在應用程式中加入地圖 ID

如要使用上一步建立的地圖 ID,請開啟 ViewController.swift 檔案,並在 loadView 方法中建立 GMSMapID 物件,然後提供地圖 ID。接著,提供 GMSMapID 物件做為參數,修改 GMSMapView 例項。

ViewController.swift

  override func loadView() {

    // Load the map at set latitude/longitude and zoom level
    let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 11)
    let mapID = GMSMapID(identifier: "YOUR_MAP_ID")

    mapView = GMSMapView(frame: .zero, mapID: mapID, camera: camera)
    self.view = mapView
    mapView.delegate = self
  }

完成後,請執行應用程式,查看所選樣式的地圖。

6. 在地圖中加入標記

開發人員可透過 Maps SDK for iOS 執行許多操作,但最受歡迎的絕對是在地圖上放置標記。標記會顯示地圖上的特定點,是處理使用者互動的常見 UI 元素。如果您使用過 Google 地圖,可能對預設標記很熟悉,也就是圖 2 中的紅色圖釘:

地圖上顯示紅色標記

圖 2. 地圖上標有紅色標記。

這個步驟說明如何使用 GMSMarker 類別在地圖上放置標記。

請注意,地圖從檢視畫面控制器的 loadView 生命週期事件載入後,才能在地圖上放置標記,因此請在 viewDidLoad 生命週期事件中完成這些步驟,該事件會在檢視畫面 (和地圖) 載入後呼叫。

  1. 定義 CLLocationCoordinate2D 物件。

CLLocationCoordinate2D 是 iOS CoreLocation 程式庫提供的結構體,用於定義特定經緯度的地理位置。如要開始建立第一個標記,請定義 CLLocationCoordinate2D 物件,並將緯度和經度設為地圖中心。地圖中心的座標可透過 camera.target.latitude 和 camera.target.longitude 屬性從地圖檢視畫面存取。

    // Add a single marker with a custom icon
    let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
  1. 建立 GMSMarker 的執行個體。

Maps SDK for iOS 提供 GMSMarker 類別。每個 GMSMarker 例項都代表地圖上的個別標記,並透過呼叫 markerWithPosition: 建立,然後將 CLLocationCoordinate2D 物件傳遞至該例項,告知 SDK 在地圖上放置標記的位置。

    let marker = GMSMarker(position: mapCenter)
  1. 設定自訂標記圖示。

Google 地圖的預設紅色圖釘標記很棒,但自訂地圖也很不錯!幸好,使用 Maps SDK for iOS 建立自訂標記非常簡單。請注意,StarterApp 專案包含名為「custom_pin.png」的圖片供您使用,但您也可以使用任何圖片。

如要設定自訂標記,請將標記的 icon 屬性設為 UIImage 的執行個體。

    marker.icon = UIImage(named: "custom_pin.png")
  1. 將標記算繪到地圖上。

標記已建立,但尚未顯示在地圖上。如要這麼做,請將 GMSMarker 執行個體的 map 屬性設為 GMSMapView 的執行個體。

    marker.map = mapView

現在重新載入應用程式,您會看到第一個含有標記的地圖,如圖 3 所示!

iOS 應用程式,畫面中央顯示含有紅色標記的 Google 地圖

圖 3. iOS 應用程式,畫面中央顯示 Google 地圖和紅色標記。

回顧一下,在本節中,您建立了 GMSMarker 類別的例項,並將其套用至地圖檢視區塊,在地圖上顯示標記。ViewController.swift 中更新後的 viewDidLoad 生命週期事件現在應如下所示:

  override func viewDidLoad() {
    super.viewDidLoad()

    // Add a single marker with a custom icon
    let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
    let marker = GMSMarker(position: mapCenter)

    marker.icon = UIImage(named: "custom_pin.png")
    marker.map = mapView
  }

7. 啟用標記叢集功能

如果使用大量標記,或標記彼此距離很近,可能會發生標記重疊或擠在一起的問題,導致使用者體驗不佳。舉例來說,如果兩個標記非常靠近,您可能會遇到圖 4 所示的情況:

兩個標記非常靠近

圖 4. 兩個標記非常靠近。

這時標記叢集功能就能派上用場。標記叢集是另一個常見的實作功能,可將附近的標記分組為單一圖示,並根據縮放等級變更,如圖 5 所示:

標記群組化為單一圖示的範例

圖 5. 標記會叢集為單一圖示的範例。

標記叢集演算法會將地圖的可見區域劃分為格線,然後將同一儲存格中的圖示叢集化。Google 地圖平台團隊建立了一個實用的開放原始碼公用程式庫,稱為 Google Maps SDK for iOS 公用程式庫,其中包含許多功能,可自動處理標記叢集。如要進一步瞭解標記叢集,請參閱 Google 地圖平台說明文件,或前往 GitHub 查看 iOS 公用程式程式庫的來源。

  1. 在地圖中新增更多標記。

如要查看標記叢集實際的運作情形,您必須在地圖上放置大量標記。為簡化這項作業,請使用 MarkerGenerator.swift 啟動專案中提供的標記產生器。

如要在地圖中新增指定數量的標記,請在檢視畫面控制器的 viewDidLoad 生命週期中,呼叫上一個步驟程式碼下方的 MarkerGenerator(near:count:).markerArray。這個方法會在 count 中指定的標記數量,在 CLLocationCoordinate2D 物件中指定的座標周圍隨機位置建立標記。在本例中,您可以將先前建立的 mapCenter 變數傳遞給該函式。標記會以 [GMSMarker] 傳回。

    // Generate many markers
    let markerArray = MarkerGenerator(near: mapCenter, count: 100).markerArray

如要測試這麼多標記的外觀,請在 markerArray 的定義後新增下列程式碼行,然後執行應用程式。請務必註解掉這些程式碼行,再繼續下一個步驟,因為下一個步驟會使用標記叢集管理標記的顯示方式:

    // Comment the following code out if using the marker clusterer
    // to manage markers instead.
    for marker in markerArray {
      marker.map = mapView
    }
  1. 匯入 Google Maps SDK for iOS 公用程式庫。

如要將 Maps iOS 公用程式庫新增為專案的依附元件,請在 ViewController.swift 頂端的依附元件清單中加入下列項目:

import GoogleMapsUtils
  1. 設定標記叢集。

如要使用標記叢集器,您必須提供三項資訊來設定運作方式:叢集演算法、圖示產生器和算繪器。演算法會決定標記的叢集方式,例如要納入同一叢集的標記之間的距離。圖示產生器會提供不同縮放等級使用的叢集圖示。算繪器會處理地圖上叢集圖示的實際算繪作業。

你也可以選擇從頭撰寫所有內容。或者,您也可以使用 Maps iOS 公用程式庫提供的預設實作方式,加快這個程序。新增以下幾行內容:

    // Set up the cluster manager with a supplied icon generator and renderer.
    let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
    let iconGenerator = GMUDefaultClusterIconGenerator()
    let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
  1. 建立 GMUClusterManager 的執行個體。

GMUClusterManager 類別會使用您指定的演算法、圖示產生器和轉譯器,實作標記叢集。如要建立算繪器並提供給地圖檢視區塊,請先將例項變數新增至 ViewController 實作,以儲存叢集管理工具例項:

class ViewController: UIViewController, GMSMapViewDelegate {

  private var mapView: GMSMapView!
  private var clusterManager: GMUClusterManager!
}

接著,在 viewDidLoad 生命週期事件中建立 GMUClusterManager 的例項:

    clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
  1. 新增標記並執行標記叢集。

設定標記叢集器例項後,請呼叫 add(items:),將要叢集的標記陣列傳遞至叢集管理員,然後呼叫 cluster 執行叢集器。

    clusterManager.setMapDelegate(self)
    clusterManager.add(markerArray)
    clusterManager.cluster()

重新載入應用程式,現在應該會看到許多標記整齊地叢集在一起,如圖 6 所示。請在地圖上雙指撥動縮放,試試不同的縮放等級,看看標記叢集如何隨著縮放調整。

含有 Google 地圖和叢集標記的 iOS 應用程式

圖 6:含有 Google 地圖和叢集標記的 iOS 應用程式。

回顧一下,在這個步驟中,您從 Google Maps SDK for iOS 公用程式庫設定了標記叢集工具的執行個體,然後用來將地圖上的 100 個標記叢集化。ViewController.swift 中的 viewDidLoad 生命週期事件現在應如下所示:

  override func viewDidLoad() {
    super.viewDidLoad()

    // Add a single marker with a custom icon
    let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
    let marker = GMSMarker(position: mapCenter)

    marker.icon = UIImage(named: "custom_pin.png")
    marker.map = mapView

    // Generate many markers
    let markerArray = MarkerGenerator(near: mapCenter, count: 100).markerArray
    // Comment the following code out if using the marker clusterer
    // to manage markers instead.
    //    for marker in markerArray {
    //      marker.map = mapView
    //    }

    // Set up the cluster manager with a supplied icon generator and renderer.
    let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
    let iconGenerator = GMUDefaultClusterIconGenerator()
    let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
    clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)

    clusterManager.setMapDelegate(self)
    clusterManager.add(markerArray)
    clusterManager.cluster()
  }

8. 加入使用者互動

現在您已擁有美觀的地圖,可顯示標記並使用標記叢集功能。在這個步驟中,您將使用先前設為檢視畫面控制器的 GMSMapViewDelegate,新增一些使用者互動的處理方式,以改善地圖的使用者體驗。

Maps SDK for iOS 提供完善的事件系統,可透過地圖檢視區塊委派實作,包括事件處理常式,讓您在發生各種使用者互動時執行程式碼。舉例來說,MapView 委派項目包含的方法可讓您觸發互動的程式碼執行作業,例如使用者點選地圖和標記、平移地圖檢視畫面、放大及縮小等。

在這個步驟中,您會透過程式輔助方式平移地圖,將使用者輕觸的任何標記置中。

  1. 實作標記輕觸事件監聽器。

每當使用者輕觸您先前建立的其中一個標記,以及輕觸標記叢集時 (標記叢集在內部會實作為 GMSMarker 的執行個體),系統就會呼叫 mapView(_:didTap:)。

如要實作事件監聽器,請先在結尾大括號前的 ViewController.swift 底部將其存根化。

  func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {

    return false
  }

請注意,這個方法會傳回 false。這樣做會告知 iOS SDK 繼續執行預設的 GMSMarker 行為,例如在執行事件處理常式程式碼後,顯示已設定的資訊視窗。

  1. 處理輕觸事件,並在輕觸標記或標記叢集時,將攝影機動畫設為地圖重新置中。

呼叫時,mapView(_:didTap:) 會傳遞已輕觸的 GMSMarker 例項,方便您在程式碼中處理。您可以在事件處理常式中,從地圖檢視區塊呼叫 animate(toLocation:),並從 position 屬性傳遞標記例項的位置,藉此使用這個例項重新置中地圖。

    // Animate to the marker
    mapView.animate(toLocation: marker.position)
  1. 輕觸標記叢集時放大。

常見的使用者體驗模式是,在輕觸標記叢集時放大顯示。這樣一來,使用者就能在縮放等級較低時查看叢集標記,因為叢集會展開。

如先前所述,標記叢集圖示實際上是實作 GMSMarker,並使用自訂圖示。那麼,如何判斷使用者輕觸的是標記還是標記叢集?標記叢集管理工具建立新的叢集圖示時,會實作 GMSMarker 的執行個體,以符合名為 GMUCluster. 的通訊協定。您可以使用條件式,檢查傳遞至事件處理常式的標記是否符合這項通訊協定。

以程式輔助方式得知叢集遭到輕觸後,您可以在地圖檢視區塊執行個體上呼叫 animate(toZoom:),並將縮放等級設為目前的縮放等級加一。您可以在 camera.zoom 屬性中,透過 mapView 執行個體取得目前的縮放等級。

此外,請注意下列程式碼如何傳回 true。這會告知事件處理常式您已完成事件處理,且不要在處理常式中執行任何其他程式碼。這麼做的原因之一,是為了防止基礎 GMSMarker 物件執行其餘預設行為,例如顯示資訊視窗,這在輕觸叢集圖示時沒有多大意義。

    // If the tap was on a marker cluster, zoom in on the cluster
    if let _ = marker.userData as? GMUCluster {
      mapView.animate(toZoom: mapView.camera.zoom + 1)
      return true
    }

現在重新載入應用程式,然後輕觸一些標記和標記叢集。輕觸任一元素時,地圖會以該元素為中心。輕觸標記叢集時,地圖也會放大一個等級,標記叢集會展開,顯示下方叢集的標記。

回顧一下,在這個步驟中,您實作了標記輕觸事件監聽器,並處理事件,以便在輕觸的元素上重新置中,並在該元素是標記叢集圖示時放大。

您的 mapView(_:didTap:) 方法應如下所示:

  func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {

    // Animate to the marker
    mapView.animate(toLocation: marker.position)

    // If the tap was on a marker cluster, zoom in on the cluster
    if let _ = marker.userData as? GMUCluster {
      mapView.animate(toZoom: mapView.camera.zoom + 1)
      return true
    }

    return false
  }

9. 在地圖上繪圖

到目前為止,您已建立雪梨地圖,其中顯示 100 個隨機點的標記,並處理使用者互動。在本程式碼研究室的最後一個步驟中,您會使用 Maps SDK for iOS 的繪圖功能,在地圖體驗中新增實用功能。

假設使用者想探索雪梨市,並使用這張地圖。如果點選標記時能顯示半徑,會是很有用的功能。這樣一來,使用者就能快速瞭解點選的標記附近有哪些其他目的地。

iOS SDK 包含一組函式,可在地圖上繪製形狀,例如正方形、多邊形、線條和圓形。在這個步驟中,請算繪圓圈,在點選標記時,顯示標記周圍 800 公尺 (約半英里) 的半徑。

  1. 在 ViewController 的實作中新增 circle 執行個體變數。

這個例項變數用於儲存最近繪製的圓形,以便在繪製另一個圓形前將其銷毀。畢竟,如果每個輕觸的標記都畫上圓圈,對使用者來說不會很有幫助,看起來也不美觀!

如要這麼做,請更新 ViewController 的實作方式,如下所示:

class ViewController: UIViewController, GMSMapViewDelegate {

  private var mapView: GMSMapView!
  private var clusterManager: GMUClusterManager!
  private var circle: GMSCircle? = nil
  ...
}
  1. 輕觸標記時繪製圓圈。

在 mapView(_:didTap:) 方法底部的 return false 陳述式上方,新增此處顯示的程式碼,建立 iOS SDK 的 GMSCircle 類別執行個體,藉由呼叫 GMSCircle(position:radius:) 並傳遞輕觸標記的位置,繪製新的 800 公尺半徑圓形,就像您最近重新置中地圖時一樣。

    // Draw a new circle around the tapped marker
    circle = GMSCircle(position: marker.position, radius: 800)
  1. 設定圓圈樣式。

根據預設,GMSCircle 會繪製黑色筆觸的圓形,並填滿透明色。這樣可以顯示半徑,但看起來不太美觀,而且有點難以辨識。接著,將 UIColor 指派給圓形的 fillColor 屬性,為圓形填入顏色,改善樣式。這裡顯示的程式碼會新增透明度為 50% 的灰色填滿:

    circle?.fillColor = UIColor(red: 0.67, green: 0.67, blue: 0.67, alpha: 0.5)
  1. 在地圖上算繪圓圈。

就像先前建立標記時一樣,建立 GMSCircle 的例項不會讓標記顯示在地圖上。如要這麼做,請將地圖檢視區塊例項指派給圓形的 map 屬性。

    circle?.map = mapView
  1. 移除先前算繪的圓圈。

如先前所述,在 Google 地圖上不斷新增圓圈,並非良好的使用者體驗。如要移除先前輕觸事件所算繪的圓圈,請將 mapView(_:didTap:) 頂端的 circle map 屬性設為 nil。

    // Clear previous circles
    circle?.map = nil

重新載入應用程式,然後輕觸標記。如圖 7 所示,每當輕觸標記時,系統就會繪製新的圓圈,並移除先前算繪的圓圈。

使用者輕觸標記後,系統會在標記周圍繪製圓圈

圖 7. 使用者點選標記後,系統會以圓圈標示該標記。

回顧一下,在這個步驟中,您使用了 GMSCircle 類別,在輕觸標記時算繪圓圈。

mapView(_:didTap:) 方法應如下所示:

  func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {

    // Clear previous circles
    circle?.map = nil

    // Animate to the marker
    mapView.animate(toLocation: marker.position)

    // If the tap was on a marker cluster, zoom in on the cluster
    if let _ = marker.userData as? GMUCluster {
      mapView.animate(toZoom: mapView.camera.zoom + 1)
      return true
    }

    // Draw a new circle around the tapped marker
    circle = GMSCircle(position: marker.position, radius: 800)
    circle?.fillColor = UIColor(red: 0.67, green: 0.67, blue: 0.67, alpha: 0.5)
    circle?.map = mapView
    return false
  }

10. 恭喜

您已成功建構 iOS 應用程式,其中包含互動式 Google 地圖。

您學到的內容

後續步驟

  • 探索或建立 maps-sdk-for-ios-samples GitHub 範例和示範存放區的分支,取得更多靈感
  • 透過更多 Swift 程式碼研究室,瞭解如何使用 Google 地圖平台建構 iOS 應用程式
  • 請填寫下列問卷調查,協助我們製作最實用的內容:

你還想看到哪些程式碼研究室?

在地圖上以視覺化方式呈現資料 進一步瞭解如何自訂地圖樣式 在地圖中建構 3D 互動

找不到最感興趣的程式碼研究室嗎?請在這裡提出新的問題。