Karte in Ihre iOS-App einfügen (Swift)

1. Vorbereitung

In diesem Codelab erfahren Sie, wie Sie die Google Maps Platform zum Erstellen von iOS-Apps in Swift verwenden. Sie erstellen eine iOS-App, die Folgendes kann:

  • Lädt das Maps SDK for iOS und die Maps SDK for iOS-Dienstprogrammbibliothek.
  • Zeigt eine Karte an, auf der Sydney, Australien, in der Mitte liegt.
  • Zeigt benutzerdefinierte Markierungen für 100 Punkte in der Umgebung von Sydney an.
  • Implementiert Markierungscluster.
  • Ermöglicht Nutzerinteraktionen, bei denen die Karte neu zentriert und ein Kreis auf der Karte gezeichnet wird, wenn auf eine Markierung getippt wird.

Karte mit Markierungen in einer iOS-App

Vorbereitung

  • Grundkenntnisse in Swift und iOS-Entwicklung

Aufgaben

  • Laden Sie das Maps SDK for iOS und die Google Maps SDK for iOS Utility Library.
  • Karte laden
  • Markierungen, benutzerdefinierte Markierungen und Markierungscluster verwenden
  • Nutzerinteraktionen mit dem Maps SDK for iOS-Ereignissystem unterstützen
  • Kamera der Karte programmatisch steuern
  • Zeichnen Sie auf der Karte.

Voraussetzungen

Für dieses Codelab benötigen Sie die folgenden Konten, Dienste und Tools:

  • Xcode 12.0 oder höher mit einem Ziel-SDK von 12.0 oder höher.
  • CocoaPods muss installiert sein.
  • Ein Google Cloud Platform-Konto mit aktivierter Abrechnung (siehe nächster Schritt).
  • Ein Projekt in der Cloud Console, für das das Maps SDK for iOS aktiviert ist (siehe nächsten Schritt).

2. Einrichten

Für den Aktivierungsschritt unten müssen Sie das Maps SDK for iOS aktivieren.

Google Maps Platform einrichten

Wenn Sie noch kein Google Cloud-Konto und kein Projekt mit aktivierter Abrechnung haben, lesen Sie bitte den Leitfaden Erste Schritte mit Google Maps Platform, um ein Rechnungskonto und ein Projekt zu erstellen.

  1. Klicken Sie in der Cloud Console auf das Drop-down-Menü für das Projekt und wählen Sie das Projekt aus, das Sie für dieses Codelab verwenden möchten.

  1. Aktivieren Sie die für dieses Codelab erforderlichen APIs und SDKs der Google Maps Platform im Google Cloud Marketplace. Folgen Sie dazu der Anleitung in diesem Video oder dieser Dokumentation.
  2. Generieren Sie einen API-Schlüssel in der Cloud Console auf der Seite Anmeldedaten. Folgen Sie dazu dieser Anleitung oder dieser Dokumentation. Für alle Anfragen an die Google Maps Platform ist ein API-Schlüssel erforderlich.

Kurzanleitung

Damit Sie so schnell wie möglich loslegen können, finden Sie hier einige Startcodes, die Ihnen helfen, diesem Codelab zu folgen.

  1. Klonen Sie das Repository, wenn Sie git installiert haben.
git clone https://github.com/googlemaps/codelab-maps-platform-101-swift.git

Alternativ können Sie auf Gib mir den Code klicken, um den Quellcode herunterzuladen.

  1. Öffnen Sie nach dem Herunterladen des Codes das Projekt „StarterApp“ im Verzeichnis /starter. Dieses Projekt enthält die grundlegende Dateistruktur, die Sie für das Codelab benötigen. Alle benötigten Dateien befinden sich im Verzeichnis /starter/StarterApp.

Den vollständigen Lösungscode finden Sie im Verzeichnis /solution/SolutionApp.

3. Maps SDK for iOS installieren

Als Erstes müssen Sie die erforderlichen Abhängigkeiten installieren, um das Maps SDK for iOS verwenden zu können. Dieser Prozess umfasst zwei Schritte: die Installation des Maps SDK for iOS und der Maps SDK for iOS Utility Library über den Cocoapods-Abhängigkeitsmanager sowie die Bereitstellung Ihres API-Schlüssels für das SDK.

  1. Fügen Sie Podfile das Maps SDK for iOS und die Maps SDK for iOS Utility Library hinzu.

In diesem Codelab werden sowohl das Maps SDK for iOS, das alle Kernfunktionen von Google Maps bietet, als auch die Maps iOS Utility Library verwendet, die eine Vielzahl von Dienstprogrammen zur Erweiterung Ihrer Karte bietet, einschließlich Markierungs-Clustering.

Öffnen Sie zuerst Podfile in Xcode (oder in Ihrem bevorzugten Texteditor) und fügen Sie unter dem Kommentar # Pods for StarterApp die Abhängigkeiten für das Maps SDK for iOS und die Dienstprogrammbibliothek hinzu:

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

In der Dokumentation zum Maps SDK for iOS unter Versionen finden Sie die aktuelle Version des SDKs und Informationen zur Wartung.

Ihr Podfile sollte so aussehen:

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. Installieren Sie die Pods für das Maps SDK for iOS und die Maps SDK for iOS Utility Library.

Führen Sie zum Installieren der Abhängigkeiten den Befehl pod install in der Befehlszeile im Verzeichnis /starter aus. Cocoapods lädt die Abhängigkeiten automatisch herunter und erstellt StarterApp.xcworkspace.

  1. Sobald die Abhängigkeiten installiert sind, führen Sie open StarterApp.xcworkspace aus dem Verzeichnis /starter aus, um die Datei in Xcode zu öffnen. Führen Sie die App dann im iPhone-Simulator aus, indem Sie Command+R drücken. Wenn alles richtig eingerichtet ist, wird der Simulator gestartet und ein schwarzer Bildschirm angezeigt. Keine Sorge, du hast noch nichts erstellt. Das ist also ganz normal.
  2. Importieren Sie das SDK in AppDelegate.swift.

Nachdem die Abhängigkeiten installiert sind, müssen Sie dem SDK Ihren API-Schlüssel zur Verfügung stellen. Als Erstes müssen Sie das Maps SDK for iOS als Abhängigkeit importieren. Fügen Sie dazu Folgendes unter der import UIKit-Importanweisung ein:

import GoogleMaps
  1. Übergeben Sie Ihren API-Schlüssel an das iOS SDK, indem Sie provideAPIKey für GMSServices in application: didFinishLaunchingWithOptions: aufrufen.
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

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

    return true
  }

Ihre aktualisierte AppDelegate.swift-Datei sollte jetzt so aussehen:

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
  }

}

Ersetzen Sie YOUR_API_KEY durch den API-Schlüssel, den Sie in der Cloud Console erstellt haben.

Nachdem Sie die Abhängigkeiten installiert und Ihren API-Schlüssel angegeben haben, können Sie mit dem Aufrufen des Maps SDK for iOS beginnen.

4. Karte anzeigen

Es ist an der Zeit, Ihre erste Karte zu präsentieren.

Der am häufigsten verwendete Teil des Maps SDK for iOS ist die Klasse GMSMapView, die viele der Methoden bereitstellt, mit denen Sie Karteninstanzen erstellen und bearbeiten können. So gehts:

  1. Öffnen Sie ViewController.swift.

Hier erledigen Sie den Rest der Aufgaben für dieses Codelab. Die Lebenszyklusereignisse loadView und viewDidLoad für den Ansichtscontroller sind bereits für Sie vorbereitet.

  1. Importieren Sie das Maps SDK for iOS, indem Sie Folgendes oben in die Datei einfügen:
import GoogleMaps
  1. Deklarieren Sie eine ViewController-Instanzvariable zum Speichern von GMSMapView.

Die Instanz von GMSMapView ist das Hauptobjekt, mit dem Sie in diesem Codelab arbeiten. Sie wird in verschiedenen Methoden des View-Controller-Lebenszyklus referenziert und verwendet. Damit sie verfügbar ist, müssen Sie die Implementierung von ViewController aktualisieren, um eine Instanzvariable zu deklarieren, in der sie gespeichert wird:

class ViewController: UIViewController {

  private var mapView: GMSMapView!

  ...
}
  1. Erstelle in loadView eine Instanz von GMSCameraPosition.

Mit GMSCameraPosition wird festgelegt, wo die Karte zentriert wird und welche Zoomstufe angezeigt wird. Mit diesem Code wird die Methode cameraWithLatitude:longitude:zoom: aufgerufen, um die Karte auf Sydney (Australien) zu zentrieren. Der Breitengrad ist -33,86, der Längengrad 151,20 und die Zoomstufe 12:

let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 12)
  1. Erstellen Sie in loadView eine Instanz von GMSMapView, um die Karte zu instanziieren.

Rufen Sie GMSMapView(frame: CGRect, camera: GMSCameraPosition) auf, um eine neue Karteninstanz zu erstellen. Beachten Sie, dass der Frame auf CGRect.zero festgelegt ist. Das ist eine globale Variable aus der iOS-Bibliothek CGGeometry, die einen Frame mit einer Breite und Höhe von 0 angibt, der sich an der Position (0,0) im Viewcontroller befindet. Die Kamera wird auf die gerade erstellte Kameraposition eingestellt.

Als Nächstes legen Sie die Root-Ansicht des Ansichts-Controllers auf mapView fest, damit die Karte im Vollbildmodus angezeigt wird.

    mapView = GMSMapView(frame: .zero, camera: camera)
    self.view = mapView
  1. Setzen Sie GMSMapViewDelegate auf den Ansichtscontroller.

Wenn Sie den Delegaten für die Kartenansicht implementieren, können Sie Ereignisse aus Nutzerinteraktionen in der GMSMapView-Instanz verarbeiten, die Sie später benötigen.

Aktualisieren Sie zuerst die Schnittstelle von ViewController, damit sie dem Protokoll für GMSMapViewDelegate: entspricht.

class ViewController: UIViewController, GMSMapViewDelegate

Fügen Sie als Nächstes die folgende Zeile in die Funktion loadView ein, um GMSMapViewDelegate auf ViewController festzulegen.

    mapView.delegate = self

Laden Sie die App nun im iOS-Simulator neu (Command+R). Die Karte sollte wie im folgenden Screenshot angezeigt werden:

iOS-App mit einer Google-Karte

Abbildung 1. iOS-App mit einer Google-Karte.

Zusammenfassend lässt sich sagen, dass Sie in diesem Schritt eine Instanz von GMSMapView erstellt haben, um eine Karte mit der Stadt Sydney, Australien, im Mittelpunkt anzuzeigen.

Ihre ViewController.swift-Datei sollte jetzt so aussehen:

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. Karte gestalten (optional)

Sie können den Stil Ihrer Karte mit cloudbasiertem Gestalten von Karteninhalten anpassen.

Karten-ID erstellen

Wenn Sie noch keine Karten-ID mit einem zugehörigen Kartenstil erstellt haben, folgen Sie der Anleitung unter Karten-IDs, um die folgenden Schritte auszuführen:

  1. Erstellen Sie eine Karten-ID.
  2. Verknüpfen Sie eine Karten-ID mit einem Kartenstil.

Karten-ID in App einbinden

Wenn Sie die im vorherigen Schritt erstellte Karten-ID verwenden möchten, öffnen Sie die Datei ViewController.swift und erstellen Sie in der Methode loadView ein GMSMapID-Objekt und geben Sie die Karten-ID an. Ändern Sie als Nächstes die GMSMapView-Instanziierung, indem Sie das GMSMapID-Objekt als Parameter angeben.

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
  }

Wenn Sie das erledigt haben, führen Sie die App aus, um die Karte im ausgewählten Stil zu sehen.

6. Markierungen zur Karte hinzufügen

Entwickler nutzen das Maps SDK for iOS für viele verschiedene Zwecke, aber das Platzieren von Markierungen auf der Karte ist definitiv am beliebtesten. Markierungen zeigen bestimmte Punkte auf der Karte an und sind ein gängiges UI-Element für die Verarbeitung von Nutzerinteraktionen. Wenn Sie Google Maps schon einmal verwendet haben, kennen Sie wahrscheinlich die Standardmarkierung, die wie die roten Pins in Abbildung 2 aussieht:

Karte mit roten Markierungen

Abbildung 2: Karte mit roten Markierungen

In diesem Schritt wird gezeigt, wie Sie mit der Klasse GMSMarker Markierungen auf der Karte platzieren.

Markierungen können erst auf der Karte platziert werden, nachdem die Karte im loadView-Lebenszyklusereignis des Ansichts-Controllers geladen wurde. Führen Sie diese Schritte also im viewDidLoad-Lebenszyklusereignis aus, das aufgerufen wird, nachdem die Ansicht (und die Karte) geladen wurde.

  1. Definieren Sie ein CLLocationCoordinate2D-Objekt.

CLLocationCoordinate2D ist eine Struktur, die von der iOS-Bibliothek CoreLocation bereitgestellt wird und einen geografischen Standort mit einem bestimmten Breiten- und Längengrad definiert. Um Ihre erste Markierung zu erstellen, definieren Sie ein CLLocationCoordinate2D-Objekt und legen Sie den Breiten- und Längengrad auf den Mittelpunkt der Karte fest. Auf die Koordinaten des Kartenmittelpunkts wird über die Eigenschaften camera.target.latitude und camera.target.longitude in der Kartenansicht zugegriffen.

    // Add a single marker with a custom icon
    let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
  1. Erstellen Sie eine Instanz von GMSMarker.

Das Maps SDK for iOS bietet die Klasse GMSMarker. Jede Instanz von GMSMarker stellt eine einzelne Markierung auf der Karte dar. Sie wird durch Aufrufen von markerWithPosition: und Übergeben eines CLLocationCoordinate2D-Objekts erstellt, um dem SDK mitzuteilen, wo die Markierung auf der Karte platziert werden soll.

    let marker = GMSMarker(position: mapCenter)
  1. Ein benutzerdefiniertes Markierungssymbol festlegen

Die standardmäßige rote Stecknadel von Google Maps ist zwar praktisch, aber es gibt noch viele andere Möglichkeiten, Ihre Karte zu gestalten. Mit dem Maps SDK for iOS ist die Verwendung einer benutzerdefinierten Markierung ganz einfach. Das StarterApp-Projekt enthält ein Bild namens „custom_pin.png“, das Sie verwenden können. Sie können aber auch ein beliebiges anderes Bild verwenden.

Um die benutzerdefinierte Markierung festzulegen, setzen Sie die Eigenschaft icon der Markierung auf eine Instanz von UIImage.

    marker.icon = UIImage(named: "custom_pin.png")
  1. Rendern Sie die Markierung auf der Karte.

Ihre Markierung wurde erstellt, ist aber noch nicht auf der Karte zu sehen. Dazu setzen Sie die Eigenschaft map der GMSMarker-Instanz auf eine Instanz von GMSMapView.

    marker.map = mapView

Laden Sie die App jetzt neu. Sie sehen nun Ihre erste Karte mit einer Markierung, wie in Abbildung 3 dargestellt.

iOS-App mit einer Google-Karte mit einer roten Markierung in der Mitte

Abbildung 3. iOS-App mit einer Google Maps-Karte mit einer roten Markierung in der Mitte.

Zusammenfassend lässt sich sagen, dass Sie in diesem Abschnitt eine Instanz der Klasse „GMSMarker“ erstellt und auf die Kartenansicht angewendet haben, um eine Markierung auf der Karte anzuzeigen. Das aktualisierte Lebenszyklus-Ereignis „viewDidLoad“ in ViewController.swift sollte jetzt so aussehen:

  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. Marker-Clustering aktivieren

Wenn Sie viele Markierungen verwenden oder Markierungen, die sich in unmittelbarer Nähe zueinander befinden, kann es vorkommen, dass sie sich überlappen oder zu dicht beieinander angezeigt werden. Das kann die Nutzerfreundlichkeit beeinträchtigen. Wenn beispielsweise zwei Markierungen sehr nahe beieinander liegen, kann es zu einer Situation wie in Abbildung 4 kommen:

Zwei Markierungen sehr nah beieinander

Abbildung 4: Zwei Markierungen liegen sehr nah beieinander.

Hier kommt das Markierungsclustering ins Spiel. Das Markierungs-Clustering ist eine weitere häufig implementierte Funktion, bei der nahe beieinander liegende Markierungen in einem einzelnen Symbol gruppiert werden, das sich je nach Zoomstufe ändert (siehe Abbildung 5):

Beispiel für Marker, die in einem einzelnen Symbol gruppiert sind

Abbildung 5: Beispiel für Markierungen, die in einem einzelnen Symbol zusammengefasst sind.

Beim Algorithmus für das Markierungs-Clustering wird der sichtbare Bereich der Karte in ein Raster unterteilt. Anschließend werden Symbole, die sich in derselben Zelle befinden, gruppiert. Das Google Maps Platform-Team hat eine hilfreiche Open-Source-Dienstprogrammbibliothek namens Google Maps SDK for iOS Utility Library erstellt, die unter anderem das Markierungs-Clustering automatisch für Sie übernimmt. Weitere Informationen zum Markierungs-Clustering finden Sie in der Google Maps Platform-Dokumentation oder im Quellcode der iOS Utility Library auf GitHub.

  1. Fügen Sie der Karte weitere Markierungen hinzu.

Damit Sie Markierungscluster in Aktion sehen können, müssen Sie viele Markierungen auf der Karte haben. Um dies zu vereinfachen, können Sie den Markierungsgenerator verwenden, der im Starterprojekt in MarkerGenerator.swift enthalten ist.

Wenn Sie eine bestimmte Anzahl von Markierungen auf Ihrer Karte hinzufügen möchten, rufen Sie MarkerGenerator(near:count:).markerArray im viewDidLoad-Lebenszyklus des Ansichts-Controllers unter dem Code aus dem vorherigen Schritt auf. Mit der Methode wird die in count angegebene Anzahl von Markierungen an zufälligen Positionen um die in einem CLLocationCoordinate2D-Objekt angegebenen Koordinaten erstellt. In diesem Fall können Sie die zuvor erstellte Variable mapCenter übergeben. Die Markierungen werden in einem [GMSMarker] zurückgegeben.

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

Sie können testen, wie viele Markierungen angezeigt werden, indem Sie diese Zeilen nach der Definition von markerArray hinzufügen und die App dann ausführen. Kommentieren Sie diese Zeilen aus, bevor Sie mit den nächsten Schritten fortfahren, bei denen der Marker Clusterer verwendet wird, um die Anzeige der Markierungen zu verwalten:

    // Comment the following code out if using the marker clusterer
    // to manage markers instead.
    for marker in markerArray {
      marker.map = mapView
    }
  1. Importieren Sie die Google Maps SDK for iOS-Dienstprogrammbibliothek.

Wenn Sie die Maps iOS-Dienstprogrammbibliothek als Abhängigkeit zu Ihrem Projekt hinzufügen möchten, fügen Sie Folgendes der Liste der Abhängigkeiten oben in ViewController.swift hinzu:

import GoogleMapsUtils
  1. Konfigurieren Sie den Markierungscluster.

Um den Marker-Clusterer zu verwenden, müssen Sie drei Dinge angeben, um seine Funktionsweise zu konfigurieren: einen Clustering-Algorithmus, einen Symbolgenerator und einen Renderer. Der Algorithmus bestimmt das Verhalten beim Clustern von Markierungen, z. B. den Abstand zwischen Markierungen, die in denselben Cluster aufgenommen werden sollen. Der Symbolgenerator stellt die Clustersymbole bereit, die auf verschiedenen Zoomstufen verwendet werden sollen. Der Renderer übernimmt das eigentliche Rendern der Clustersymbole auf der Karte.

Sie können alle diese Elemente auch selbst schreiben. Alternativ bietet die Maps iOS-Dienstprogrammbibliothek Standardimplementierungen, um den Prozess zu beschleunigen. Fügen Sie die folgenden Zeilen hinzu:

    // 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. Erstellen Sie eine Instanz von GMUClusterManager.

GMUClusterManager ist die Klasse, die das Markierungs-Clustering mit dem von Ihnen angegebenen Algorithmus, der Symbolgenerierung und dem Renderer implementiert. Um den Renderer zu erstellen und für die Kartenansicht verfügbar zu machen, fügen Sie zuerst eine Instanzvariable zur ViewController-Implementierung hinzu, um die Cluster-Manager-Instanz zu speichern:

class ViewController: UIViewController, GMSMapViewDelegate {

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

Erstellen Sie als Nächstes die Instanz von GMUClusterManager im Lebenszyklusereignis viewDidLoad:

    clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
  1. Fügen Sie die Markierungen hinzu und führen Sie den Markierungscluster aus.

Nachdem Sie die Marker-Clusterer-Instanz konfiguriert haben, übergeben Sie das Array der zu clusternden Marker an den Cluster-Manager, indem Sie add(items:) aufrufen, und führen Sie dann den Clusterer aus, indem Sie cluster aufrufen.

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

Laden Sie Ihre App neu. Jetzt sollten viele Markierungen zu sehen sein, die wie im Beispiel in Abbildung 6 in Clustern zusammengefasst sind. Probieren Sie verschiedene Zoomstufen aus, indem Sie die Karte aufziehen und zusammenziehen. Sie werden sehen, wie sich die Markierungscluster anpassen, wenn Sie heran- oder herauszoomen.

iOS-App mit einer Google-Karte und Markierungs-Clustern

Abbildung 6: iOS-App mit Google Maps und Markierungs-Clustern.

In diesem Schritt haben Sie eine Instanz des Markierungs-Clusterers aus der Google Maps SDK for iOS Utility Library konfiguriert und dann verwendet, um 100 Markierungen auf der Karte zu clustern. Das viewDidLoad-Lebenszyklusereignis in ViewController.swift sollte jetzt so aussehen:

  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. Nutzerinteraktion hinzufügen

Sie haben jetzt eine ansprechende Karte mit Markierungen und Markierungsclustern. In diesem Schritt fügen Sie mit GMSMapViewDelegate, das Sie zuvor für den Ansichtscontroller festgelegt haben, eine zusätzliche Verarbeitung von Nutzerinteraktionen hinzu, um die Nutzerfreundlichkeit Ihrer Karte zu verbessern.

Das Maps SDK for iOS bietet ein umfassendes Ereignissystem, das über den Delegaten der Kartenansicht implementiert wird. Es enthält Event-Handler, mit denen Sie Code ausführen können, wenn verschiedene Nutzerinteraktionen stattfinden. Das MapView-Delegate enthält beispielsweise Methoden, mit denen Sie die Ausführung von Code für Interaktionen auslösen können, z. B. wenn der Nutzer auf die Karte und Markierungen klickt, die Ansicht der Karte schwenkt oder die Karte vergrößert oder verkleinert.

In diesem Schritt wird die Karte programmatisch so verschoben, dass sie auf der Markierung zentriert wird, die der Nutzer antippt.

  1. Implementieren Sie den Listener für das Tippen auf Markierungen.

mapView(_:didTap:) wird jedes Mal aufgerufen, wenn der Nutzer auf eine der Markierungen tippt, die Sie zuvor erstellt haben, und jedes Mal, wenn ein Nutzer auf einen Markierungscluster tippt (intern werden Markierungscluster als Instanz von GMSMarker implementiert).

Um den Event-Listener zu implementieren, beginnen Sie damit, ihn am Ende von ViewController.swift vor der schließenden geschweiften Klammer zu platzieren.

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

    return false
  }

Beachten Sie, dass die Methode false zurückgibt. Dadurch wird dem iOS SDK mitgeteilt, dass das Standardverhalten von GMSMarker fortgesetzt werden soll, z. B. das Anzeigen eines Infofensters, falls eines konfiguriert ist, nachdem der Event-Handler-Code ausgeführt wurde.

  1. Verarbeiten Sie das Tippereignis und animieren Sie die Kamera, um die Karte neu zu zentrieren, wenn auf eine Markierung oder ein Markierungscluster getippt wird.

Wenn mapView(_:didTap:) aufgerufen wird, übergibt es die Instanz von GMSMarker, auf die getippt wurde, damit Sie sie in Ihrem Code verarbeiten können. Sie können diese Instanz verwenden, um die Karte neu zu zentrieren. Rufen Sie dazu animate(toLocation:) in der Kartenansicht aus dem Ereignishandler auf und übergeben Sie die Position der Markierungsinstanz aus der position-Eigenschaft.

    // Animate to the marker
    mapView.animate(toLocation: marker.position)
  1. Auf einen Markierungscluster wird herangezoomt, wenn darauf getippt wird.

Ein gängiges UX-Muster ist das Einzoomen auf Markierungscluster, wenn darauf getippt wird. So können Nutzer die geclusterten Markierungen sehen, da sich der Cluster bei niedrigeren Zoomstufen erweitert.

Wie bereits erwähnt, ist das Markierungsclustersymbol eine Implementierung von GMSMarker mit einem benutzerdefinierten Symbol. Wie können Sie also feststellen, ob auf eine Markierung oder einen Markierungscluster getippt wurde? Wenn der Marker-Clusterer-Manager ein neues Clustersymbol erstellt, wird die Instanz von GMSMarker implementiert, um einem Protokoll namens GMUCluster. zu entsprechen. Sie können eine Bedingung verwenden, um zu prüfen, ob der an den Event-Handler übergebene Marker diesem Protokoll entspricht.

Sobald Sie programmatisch wissen, dass auf einen Cluster getippt wurde, können Sie animate(toZoom:) für die Kartenansicht-Instanz aufrufen und die Zoomstufe auf die aktuelle Zoomstufe plus eins festlegen. Die aktuelle Zoomstufe ist in der camera.zoom-Eigenschaft der mapView-Instanz verfügbar.

Beachten Sie außerdem, dass der folgende Code true zurückgibt. So wird dem Event-Handler mitgeteilt, dass Sie das Ereignis verarbeitet haben und kein weiterer Code im Handler ausgeführt werden soll. Einer der Gründe dafür ist, dass das zugrunde liegende GMSMarker-Objekt nicht den Rest seines Standardverhaltens ausführt, z. B. das Anzeigen eines Infofensters, was beim Tippen auf ein Clustersymbol nicht sinnvoll wäre.

    // 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
    }

Laden Sie die App jetzt neu und tippen Sie auf einige Markierungen und Markierungscluster. Wenn Sie auf eines der beiden Elemente tippen, wird die Karte auf das angetippte Element zentriert. Wenn auf einen Markierungscluster getippt wird, wird die Karte um eine Stufe vergrößert und der Markierungscluster wird erweitert, um die darunter gruppierten Markierungen anzuzeigen.

In diesem Schritt haben Sie den Listener für das Tippen auf Markierungen implementiert und das Ereignis so verarbeitet, dass die Karte auf dem angetippten Element zentriert und vergrößert wird, wenn es sich um ein Markierungsclustersymbol handelt.

Ihre mapView(_:didTap:)-Methode sollte so aussehen:

  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. Auf der Karte zeichnen

Bisher haben Sie eine Karte von Sydney erstellt, auf der Markierungen an 100 zufälligen Punkten angezeigt werden und die Nutzerinteraktionen verarbeitet. Im letzten Schritt dieses Codelabs verwenden Sie die Zeichenfunktionen des Maps SDK for iOS, um Ihrer Karte eine zusätzliche nützliche Funktion hinzuzufügen.

Stellen Sie sich vor, diese Karte wird von Nutzern verwendet, die die Stadt Sydney erkunden möchten. Eine nützliche Funktion wäre, einen Radius um eine Markierung zu visualisieren, wenn darauf geklickt wird. So kann der Nutzer schnell erkennen, welche anderen Ziele sich in der Nähe der angeklickten Markierung befinden.

Das iOS SDK enthält eine Reihe von Funktionen zum Zeichnen von Formen auf der Karte, z. B. Quadrate, Polygone, Linien und Kreise. In diesem Schritt rendern Sie einen Kreis mit einem Radius von 800 Metern (etwa einer halben Meile) um eine Markierung, wenn darauf geklickt wird.

  1. Fügen Sie der Implementierung des ViewController eine circle-Instanzvariable hinzu.

In dieser Instanzvariablen wird der zuletzt gezeichnete Kreis gespeichert, damit er gelöscht werden kann, bevor ein weiterer Kreis gezeichnet wird. Es wäre schließlich nicht sehr hilfreich für den Nutzer und würde auch nicht gut aussehen, wenn jeder angetippte Marker von einem Kreis umgeben wäre.

Aktualisieren Sie dazu die Implementierung von ViewController so:

class ViewController: UIViewController, GMSMapViewDelegate {

  private var mapView: GMSMapView!
  private var clusterManager: GMUClusterManager!
  private var circle: GMSCircle? = nil
  ...
}
  1. Zeichnen Sie den Kreis, wenn auf eine Markierung getippt wird.

Fügen Sie unten in der Methode mapView(_:didTap:) direkt über der Anweisung return false den hier gezeigten Code ein, um eine Instanz der GMSCircle-Klasse des iOS SDK zu erstellen. Rufen Sie dazu GMSCircle(position:radius:) auf und übergeben Sie die Position der angetippten Markierung, wie Sie es beim Zentrieren der Karte getan haben.

    // Draw a new circle around the tapped marker
    circle = GMSCircle(position: marker.position, radius: 800)
  1. Kreis gestalten

Standardmäßig wird mit GMSCircle ein Kreis mit schwarzem Strich und transparenter Füllung gezeichnet. Das funktioniert zwar, um den Radius anzuzeigen, sieht aber nicht sehr gut aus und ist etwas schwer zu erkennen. Als Nächstes weisen Sie dem Kreis eine Füllfarbe zu, um das Design zu verbessern. Dazu weisen Sie der fillColor-Eigenschaft des Kreises einen UIColor zu. Der hier gezeigte Code fügt eine graue Füllung mit 50% Transparenz hinzu:

    circle?.fillColor = UIColor(red: 0.67, green: 0.67, blue: 0.67, alpha: 0.5)
  1. Rendern Sie den Kreis auf der Karte.

Wie beim Erstellen von Markierungen zuvor wird die GMSCircle-Instanz nicht auf der Karte angezeigt, wenn Sie sie erstellen. Weisen Sie dazu die Kartenansicht-Instanz der map-Eigenschaft des Kreises zu.

    circle?.map = mapView
  1. Entfernen Sie alle zuvor gerenderten Kreise.

Wie bereits erwähnt, wäre es nicht sehr nutzerfreundlich, der Karte immer wieder Kreise hinzuzufügen. Wenn Sie den Kreis entfernen möchten, der durch ein vorheriges Tippereignis gerendert wurde, setzen Sie die map-Eigenschaft von circle oben in mapView(_:didTap:) auf nil.

    // Clear previous circles
    circle?.map = nil

Laden Sie die App neu und tippen Sie auf eine Markierung. Jedes Mal, wenn auf eine Markierung getippt wird, sollte ein neuer Kreis gezeichnet und alle zuvor gerenderten Kreise entfernt werden (siehe Abbildung 7).

Ein Kreis um die angeklickte Markierung

Abbildung 7: Um die angeklickte Markierung wird ein Kreis gezeichnet.

Zusammenfassend lässt sich sagen, dass Sie in diesem Schritt die Klasse GMSCircle verwendet haben, um einen Kreis zu rendern, wenn auf eine Markierung getippt wird.

Die mapView(_:didTap:)-Methode sollte so aussehen:

  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. Glückwunsch

Sie haben eine iOS-App mit einer interaktiven Google-Karte erstellt.

Das haben Sie gelernt

Nächste Schritte

  • Weitere Inspirationen finden Sie im maps-sdk-for-ios-samples GitHub-Repository mit Beispielen und Demos. Sie können es auch forken.
  • Weitere Swift-Codelabs zum Erstellen von iOS-Apps mit der Google Maps Platform
  • Helfen Sie uns, die Inhalte zu erstellen, die für Sie am nützlichsten sind, indem Sie die folgende Umfrage beantworten:

Welche anderen Codelabs würden Sie sich wünschen?

Datenvisualisierung auf Karten Weitere Informationen zum Anpassen des Stils von Karten 3D-Interaktionen in Karten entwickeln

Sie können das Codelab, das Sie am meisten interessiert, nicht finden? Hier können Sie sie mit einem neuen Problem anfordern.