Dodawanie mapy do aplikacji na iOS (Swift)

1. Zanim zaczniesz

Dzięki nim dowiesz się, jak zacząć korzystać z Google Maps Platform do tworzenia aplikacji na iOS w Swift. Utworzysz aplikację na iOS, która:

  • Wczyta pakiet SDK Maps na iOS i bibliotekę narzędziową Maps na iOS.
  • Wyświetla mapę wyśrodkowaną w Sydney w Australii.
  • Wyświetla niestandardowe znaczniki 100 punktów wokół Sydney.
  • Implementuje klastry znaczników.
  • Włącza interakcję użytkownika, która powoduje ponowne wyśrodkowanie i rysuje na mapie okrąg po kliknięciu znacznika.

Mapa ze znacznikami w aplikacji na iOS

Wymagania wstępne

  • Podstawowe informacje o programowaniu Swift i iOS.

Czego się nauczysz

  • Wczytuję pakiet SDK Maps na iOS i bibliotekę narzędzi Google Maps na iOS.
  • Wczytuję mapę.
  • używając znaczników, znaczników niestandardowych i klastrów znaczników;
  • Współpraca z systemem zdarzeń pakietu SDK Maps na iOS w celu zapewnienia interakcji z użytkownikami.
  • Automatyczne sterowanie kamerą mapy.
  • Rysowanie na mapie.

Czego potrzebujesz

Aby ukończyć ćwiczenia z programowania, potrzebujesz tych kont, usług i narzędzi:

  • Xcode 12.0 lub nowszy z docelowym pakietem SDK w wersji 12.0 lub nowszej.
  • Zainstalowano cocoapods.
  • konto Google Cloud Platform z włączonymi rozliczeniami (patrz następny krok).
  • Projekt w Cloud Console z włączonym pakietem SDK Maps na iOS (patrz następny krok).

2. Konfiguracja

Aby włączyć tę funkcję, musisz włączyć pakiet SDK Map Google na iOS.

Konfigurowanie Google Maps Platform

Jeśli nie masz jeszcze konta Google Cloud Platform ani projektu z włączonymi płatnościami, przeczytaj przewodnik Pierwsze kroki z Google Maps Platform, by utworzyć konto rozliczeniowe i projekt.

  1. W Cloud Console kliknij menu projektu i wybierz projekt, którego chcesz użyć w tym ćwiczeniu z programowania.

  1. Włącz interfejsy API i pakiety SDK Google Maps Platform wymagane w ramach tego ćwiczenia z ćwiczeń w Google Cloud Marketplace. W tym celu wykonaj czynności opisane w tym filmie lub w tej dokumentacji.
  2. Wygeneruj klucz interfejsu API na stronie Dane logowania w Cloud Console. Odpowiednie instrukcje znajdziesz w tym filmie lub w tej dokumentacji. Wszystkie żądania wysyłane do Google Maps Platform wymagają klucza interfejsu API.

Krótkie wprowadzenie

Aby ułatwić Ci rozpoczęcie tego ćwiczenia, skorzystaj z tego kodu, który ułatwia rozpoczęcie ćwiczeń z programowania.

  1. Skopiuj repozytorium, jeśli masz zainstalowane narzędzie git.
git clone https://github.com/googlemaps/codelab-maps-platform-101-swift.git

Możesz też kliknąć Podaj kod, by pobrać kod źródłowy.

  1. Po pobraniu kodu otwórz projekt StarterApp w katalogu /starter. Ten projekt obejmuje podstawową strukturę pliku potrzebną do ukończenia ćwiczeń z programowania. Wszystkie potrzebne informacje znajdziesz w katalogu /starter/StarterApp.

Aby zobaczyć pełny kod uruchomionego rozwiązania, wyświetl kompletny kod w katalogu /solution/SolutionApp.

3. Zainstaluj pakiet SDK Maps na iOS

Pierwszym krokiem do korzystania z pakietu Maps SDK na iOS jest zainstalowanie wymaganych zależności. Ten proces składa się z 2 etapów: instalacji pakietu SDK Maps na iOS oraz pakietu SDK Maps na iOS z biblioteki zależności Cocoapods i przekazanie klucza interfejsu API do pakietu SDK.

  1. Dodaj do pakietu Podfile Maps SDK na iOS oraz Maps SDK na iOS.

Te ćwiczenia z programowania wykorzystują pakiet SDK Map na iOS, który udostępnia wszystkie podstawowe funkcje Map Google, oraz bibliotekę narzędzi iOS na iOS, która udostępnia wiele narzędzi do wzbogacania mapy, w tym grupowanie znaczników.

Aby rozpocząć, w Xcode (lub preferowanym edytorze tekstu) otwórz plik Podfile i zaktualizuj plik, aby uwzględnić zależności pakietu Maps SDK na iOS i biblioteki mediów w komentarzu # Pods for StarterApp:

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

Sprawdź najnowszą wersję wersji pakietu SDK Maps na iOS i wskazówki dotyczące konserwacji.

Dane Podfile powinny wyglądać tak:

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. Zainstaluj pakiet SDK Maps na iOS i pody z biblioteki biblioteki narzędzi dla iOS.

Aby zainstalować zależności, uruchom polecenie pod install w katalogu /starter przy użyciu wiersza poleceń. Cocoapods automatycznie pobiera zależności i tworzy StarterApp.xcworkspace.

  1. Po zainstalowaniu zależności uruchom open StarterApp.xcworkspace z katalogu /starter, aby otworzyć plik w Xcode, a następnie uruchom aplikację w symulatorze iPhone'a, naciskając Command+R. Jeśli wszystko jest skonfigurowane prawidłowo, symulator uruchomi się i wyświetli się czarny ekran. Nie martw się, nie udało Ci się jeszcze stworzyć niczego, więc jest to normalne.
  2. Zaimportuj pakiet SDK do środowiska AppDelegate.swift.

Po dodaniu zależności dodaj klucz interfejsu API do pakietu SDK. Pierwszym krokiem jest zaimportowanie pakietu Maps SDK na iOS jako zależności, co umieść poniżej pod instrukcją importu import UIKit:

import GoogleMaps
  1. Przekaż swój klucz interfejsu API do pakietu SDK na iOS, wywołując provideAPIKey w GMSServices przy użyciu metody application: didFinishLaunchingWithOptions:
  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

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

    return true
  }

Twój zaktualizowany plik AppDelegate.swift powinien teraz wyglądać tak:

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
  }

}

Zastąp YOUR_API_KEY kluczem interfejsu API utworzonym w Cloud Console.

Po dodaniu zależności i dostarczeniu klucza interfejsu API możesz zacząć wywoływać pakiet SDK Maps na iOS.

4. Wyświetlanie mapy

Czas wyświetlić swoją pierwszą mapę!

Najpopularniejszym elementem pakietu SDK Maps na iOS jest klasa GMSMapView, która udostępnia wiele metod tworzenia instancji i manipulowania nimi. Jak to się robi?

  1. Otwórz aplikację ViewController.swift.

W tym miejscu wykonasz dalszą część ćwiczenia. Zwróć uwagę, że zdarzenia cyklu życia loadView i viewDidLoad kontrolera widoku zostały już usunięte.

  1. Aby zaimportować pakiet SDK Maps na iOS, dodaj na początku pliku:
import GoogleMaps
  1. Zadeklaruj zmienną instancji ViewController do przechowywania GMSMapView.

Wystąpienie GMSMapView jest głównym obiektem tego przedmiotu, z którym korzystasz w trakcie ćwiczeń z programowania. Odwołujesz się do niego i wykorzystasz je przy użyciu różnych metod cyklu życia kontrolera. Aby to zrobić, zaktualizuj implementację ViewController, aby zadeklarować zmienną instancji w celu jej przechowywania:

class ViewController: UIViewController {

  private var mapView: GMSMapView!

  ...
}
  1. W loadView utwórz instancję GMSCameraPosition.

GMSCameraPosition określa miejsce wyśrodkowania mapy i wyświetlany poziom powiększenia. Wywołuje on metodę cameraWithLatitude:longitude:zoom:, by wyśrodkować mapę na Sydney w Australii z długością geograficzną -33, 86 i długością geograficzną 151, 20 z powiększeniem 12:

let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 12)
  1. W loadView utwórz instancję GMSMapView, aby utworzyć instancję mapy.

Aby utworzyć nową instancję mapy, wywołaj GMSMapView(frame: CGRect, camera: GMSCameraPosition). Zwróć uwagę, że klatka jest ustawiona na CGRect.zero – jest to zmienna globalna z biblioteki CGGeometry na iOS, która określa 0 szerokość i 0 wysokość w pozycji (0,0) w widoku kontrolera. Aparat jest ustawiony w nowo utworzonej pozycji kamery.

Aby wyświetlić mapę, ustaw widok główny kontrolera widoku na mapView, dzięki czemu mapa będzie wyświetlana na pełnym ekranie.

    mapView = GMSMapView(frame: .zero, camera: camera)
    self.view = mapView
  1. Ustaw GMSMapViewDelegate na kontroler widoku.

Gdy to zrobisz, osoba, której przekazano dostęp do mapy, będzie obsługiwać zdarzenia związane z interakcjami użytkowników w instancji GMSMapView. Będą one potrzebne później.

Najpierw zaktualizuj interfejs dostawcy ViewController, aby był zgodny z protokołem GMSMapViewDelegate:

class ViewController: UIViewController, GMSMapViewDelegate

Następnie dodaj ten element do funkcji loadView, aby ustawić GMSMapViewDelegate na ViewController.

    mapView.delegate = self

Teraz ponownie załaduj aplikację w symulatorze systemu iOS (Command+R). Mapa powinna pojawić się na rysunku 1.

Aplikacja na iOS z mapą Google

Ilustracja 1. Aplikacja na iOS wyświetlająca mapę Google

Podsumowując: w tym kroku utworzyliśmy instancję GMSMapView, aby wyświetlić mapę wyśrodkowaną na terenie Sydney w Australii.

Twój plik ViewController.swift powinien teraz wyglądać tak:

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. Styl mapy (opcjonalnie)

Możesz dostosować styl mapy, korzystając ze stylu mapy w Google Cloud.

Utwórz identyfikator mapy

Jeśli nie masz jeszcze identyfikatora, ale nie jest on jeszcze powiązany ze stylem mapy, zapoznaj się z przewodnikiem po identyfikatorach map, by wykonać te czynności:

  1. Utwórz identyfikator mapy.
  2. Powiąż identyfikator mapy ze stylem mapy.

Dodawanie identyfikatora mapy do aplikacji

Aby użyć identyfikatora mapy utworzonego w poprzednim kroku, otwórz plik ViewController.swift, a w metodzie loadView utwórz obiekt GMSMapID i podaj go. Następnie zmodyfikuj wystąpienie GMSMapView, dodając obiekt GMSMapID jako parametr.

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
  }

Po wykonaniu tych czynności uruchom aplikację, aby zobaczyć mapę w wybranym stylu.

6. Dodawanie znaczników do mapy

Korzystając z pakietu Maps SDK na iOS, można robić wiele rzeczy, ale najpopularniejsze są umieszczanie znaczników na mapie. Znaczniki pokazują określone punkty na mapie. Są one powszechnymi elementami interfejsu użytkownika. Jeśli korzystałeś już z Map Google, prawdopodobnie znasz znacznik domyślny, który wygląda jak czerwone pinezki na rysunku 2:

Mapa z czerwonymi znacznikami

Rysunek 2. Mapa z czerwonymi znacznikami.

Ten krok pokazuje, jak użyć klasy GMSMarker do umieszczenia znaczników na mapie.

Pamiętaj, że znaczniki nie mogą pojawić się na mapie do momentu załadowania mapy z poprzedniego kroku w zdarzeniu cyklu życia w widoku „loadView”, więc wykonaj te czynności w zdarzeniu cyklu życia w viewDidLoad, które jest wywoływane po wczytaniu widoku (i mapy).

  1. Zdefiniuj obiekt CLLocationCoordinate2D.

CLLocationCoordinate2D to struktura udostępniona przez bibliotekę CoreLocation na iOS, która określa lokalizację geograficzną przy określonej szerokości i długości geograficznej. Aby utworzyć pierwszy znacznik, zdefiniuj obiekt CLLocationCoordinate2D i ustaw długość i szerokość geograficzną na środku mapy. Współrzędne środka mapy są dostępne w widoku mapy za pomocą właściwości camera.target.latitude i camera.target.longitude.

    // Add a single marker with a custom icon
    let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
  1. Utwórz instancję GMSMarker.

Maps SDK na iOS udostępnia klasę GMSMarker. Każde wystąpienie tagu GMSMarker reprezentuje pojedynczy znacznik na mapie i tworzy się go, wywołując markerWithPosition: i przekazując obiekt CLLocationCoordinate2D, aby poinformować pakiet SDK, w którym miejscu umieścić znacznik na mapie.

    let marker = GMSMarker(position: mapCenter)
  1. Ustaw ikonę niestandardowego znacznika.

Domyślny czerwony znacznik w Mapach Google to świetna sprawa, ale trzeba jeszcze dostosować mapę. Na szczęście użycie niestandardowego znacznika jest bardzo łatwe z wykorzystaniem pakietu SDK Maps na iOS. W projekcie StarterApp znajdziesz obraz o nazwie „custom_pin.png&#39”, który możesz wykorzystać, ale jeśli chcesz, możesz użyć dowolnego obrazu.

Aby ustawić znacznik niestandardowy, ustaw właściwość icon znacznika na wystąpienie UIImage.

    marker.icon = UIImage(named: "custom_pin.png")
  1. Wyświetl znacznik na mapie.

Twój znacznik został utworzony, ale nie występuje jeszcze na mapie. Aby to zrobić, we właściwości map instancji GMSMarker ustaw instancję GMSMapView.

    marker.map = mapView

Teraz ponownie wczytaj aplikację i obejrzyj pierwszą mapę ze znacznikiem, tak jak na rysunku 3.

Aplikacja na iOS z Mapą Google z czerwonym znacznikiem w środku

Ilustracja 3. Aplikacja na iOS z Mapami Google z czerwonym znacznikiem w środku.

Podsumowując: w tej sekcji tworzysz wystąpienie klasy GMSMarker i stosujesz ją w widoku mapy, by wyświetlać na niej znacznik. Zaktualizowane zdarzenie cyklu życia viewList w formacie ViewController.swift powinno wyglądać tak:

  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. Włącz klastry znaczników

Jeśli używasz wielu znaczników w pobliżu lub znajdują się one bardzo blisko siebie, możesz napotkać problem, w którym znaczniki się nakładają lub pojawiają się razem, co może negatywnie wpływać na wygodę użytkowników. Jeśli na przykład dwa znaczniki są bardzo blisko siebie, możemy dojść do sytuacji opisanej na rysunku 4:

Dwa znaczniki blisko siebie

Rysunek 4. Dwa znaczniki bardzo blisko siebie.

Tu zaczyna się grupowanie znaczników. Grupowanie znaczników jest inną powszechnie stosowaną funkcją, która grupuje znaczniki w pojedynczą ikonę i zmienia się w zależności od poziomu powiększenia, jak przedstawiono na rysunku 5:

Przykłady znaczników zebranych w jednej ikonie

Rysunek 5. Przykłady znaczników zebranych w jednej ikonie.

Algorytm grupowania znaczników dzieli widoczny obszar mapy na siatkę, a następnie grupuje ikony w tej samej komórce. Zespół Google Maps Platform stworzył przydatną bibliotekę narzędziową typu open source o nazwie Google Maps SDK for iOS Utility Biblioteka, która m.in. zajmuje się grupowaniem znaczników automatycznie. Więcej informacji o klastrze znaczników znajdziesz w dokumentacji Google Maps Platform lub możesz zapoznać się ze źródłem Biblioteki narzędzi na iOS w GitHub.

  1. Dodaj do mapy znacznie więcej znaczników.

Aby zobaczyć, jak tworzy się znaczniki w praktyce, musisz mieć ich wiele na mapie. Dla ułatwienia w projekcie startowym w MarkerGenerator.swift dostępny jest wygodny generator znaczników.

Aby dodać do mapy określoną liczbę znaczników, wywołaj MarkerGenerator(near:count:).markerArray w cyklu życia widoku viewDidLoad pod kodem widoku z poprzedniego kroku. Metoda tworzy liczbę znaczników określoną w count w losowych lokalizacjach wokół współrzędnych określonych w obiekcie CLLocationCoordinate2D. W takim przypadku możesz podać jej zmienną mapCenter utworzoną wcześniej. Znaczniki są zwracane w tagu [GMSMarker].

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

Aby sprawdzić, jak wyglądają te znaczniki, dodaj te wiersze po definicji markerArray i uruchom aplikację. Pamiętaj, aby dodać te wiersze do komentarza, zanim przejdziesz do następnego kroku. Zamiast tego skorzystaj z klastra znaczników, aby zarządzać wyświetlaniem znaczników:

    // Comment the following code out if using the marker clusterer
    // to manage markers instead.
    for marker in markerArray {
      marker.map = mapView
    }
  1. Zaimportuj pakiet SDK Map Google na iOS.

Aby dodać bibliotekę narzędzi Map Google na iOS jako zależność od projektu, dodaj to ustawienie do listy zależności u góry ViewController.swift:

import GoogleMapsUtils
  1. Skonfiguruj klaster znaczników.

Aby móc skorzystać z klastrów znaczników, musisz skonfigurować 3 funkcje jego działania: algorytm klastra, generator ikon oraz mechanizm renderowania. Algorytm określa sposób grupowania znaczników, np. odległość między znacznikami w tym samym klastrze. Generator ikon udostępnia ikony klastra do wykorzystania na różnych poziomach powiększenia. Moduł renderowania obsługuje renderowanie ikon klastrów na mapie.

Jeśli wolisz, możesz napisać je wszystkie od podstaw, ale biblioteka narzędzi Map Google na iOS udostępnia domyślne implementacje, które ułatwiają ten proces. Dodaj to:

    // 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. Utwórz instancję GMUClusterManager.

GMUClusterManager to klasa implementująca klasterowanie znaczników przy użyciu określonego przez Ciebie algorytmu, generatora ikon i mechanizmu renderowania. Aby utworzyć mechanizm renderowania i udostępnić go w widoku mapy, najpierw dodaj zmienną do implementacji ViewController do przechowywania instancji menedżera klastrów:

class ViewController: UIViewController, GMSMapViewDelegate {

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

Następnie utwórz wystąpienie GMUClusterManager w zdarzeniu cyklu życia viewDidLoad:

    clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
  1. Dodaj znaczniki i uruchom klaster znaczników.

Po skonfigurowaniu instancji klastra znaczników przekaż menedżerowi klastrów tablicę klastrów do wywołania, wywołując add(items:), a następnie uruchom klaster przez wywołanie cluster.

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

Załaduj ponownie aplikację. Zobaczysz wiele znaczników ładnie połączonych w przykład, jak widać na rysunku 6. Śmiało, możesz eksperymentować z różnymi poziomami powiększenia, naciskając i powiększając na mapie, aby zobaczyć znaczniki znaczników podczas powiększania/pomniejszania.

Aplikacja na iOS z Mapą Google i zgrupowanymi znacznikami

Ilustracja 6. Aplikacja na iOS z Mapami Google i zgrupowanymi znacznikami

Podsumowując: w tym kroku skonfigurujesz wystąpienie klastra znaczników z biblioteki pakietu SDK Map Google na iOS, a następnie użyjesz go do grupowania 100 znaczników na mapie. Twoje zdarzenie cyklu życia (viewDidLoad) w regionie ViewController.swift powinno teraz wyglądać następująco:

  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. Dodaj interakcję użytkownika

Masz teraz atrakcyjną mapę, która zawiera znaczniki i ich grupowanie. W tym kroku dodasz dodatkowe czynności związane z interakcjami użytkownika za pomocą elementu GMSMapViewDelegate, który został wcześniej skonfigurowany do kontrolera widoku, aby zwiększyć wygodę użytkowników Twojej mapy.

Maps SDK na iOS to rozbudowany system zdarzeń, który jest wdrażany za pomocą przekazywania dostępu do widoku mapy. Zawiera on moduły obsługi zdarzeń, które umożliwiają wykonywanie kodu w przypadku wystąpienia różnych interakcji z użytkownikiem. Na przykład osoba, której przekazano dostęp do MapView, korzysta z metod, które pozwalają uruchamiać kod w przypadku interakcji, takich jak klikanie mapy i znaczników, przesuwanie widoku mapy, powiększanie i pomniejszanie widoku i inne.

W tym kroku programowo przesuwasz mapę tak, aby wyśrodkowała go na klikniętym przez użytkownika znacznika.

  1. Zaimplementuj detektor kliknięć markerów.

Element mapView(_:didTap:) jest wywoływany za każdym razem, gdy użytkownik kliknie jeden ze utworzonych wcześniej znaczników, a także przy każdym kliknięciu znacznika (wewnętrznie znaczniki są zaimplementowane jako wystąpienie GMSMarker).

Aby zaimplementować detektor zdarzeń, umieść go na dole ViewController.swift przed zamykającym nawiasem klamrowym.

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

    return false
  }

Zwróć uwagę, że metoda zwraca false. Dzięki temu po uruchomieniu kodu modułu obsługi zdarzeń pakiet SDK do systemu iOS będzie nadal wykonywać domyślną funkcję GMSMarker, na przykład wyświetlać okno informacyjne, jeśli zostało skonfigurowane.

  1. Obsłuż zdarzenie kliknięcia i animuj kamerę, aby wyśrodkować mapę po kliknięciu znacznika lub klastra znaczników.

Po wywołaniu element mapView(_:didTap:) przekazuje wystąpienie elementu GMSMarker, które zostało kliknięte, dzięki czemu możesz obsłużyć je w kodzie. Możesz użyć tej instancji, aby ponownie wyśrodkować mapę, wywołując obiekt animate(toLocation:) w widoku mapy z poziomu modułu obsługi zdarzeń i przekazując go do pozycji instancji z właściwości position.

    // Animate to the marker
    mapView.animate(toLocation: marker.position)
  1. Powiększ grupę znaczników po dotknięciu.

Typowym wzorcem UX jest powiększanie klastrów znaczników po ich kliknięciu. Dzięki temu użytkownicy mogą wyświetlać znaczniki grupowania w miarę rozwijania klastra przy niższych poziomach powiększenia.

Jak wspomnieliśmy wcześniej, ikona klastra znaczników jest implementacją GMSMarker z ikoną niestandardową. Jak stwierdzić, czy znacznik lub klaster został kliknięty? Gdy menedżer klastra znaczników utworzy nową ikonę klastra, implementuje wystąpienie GMSMarker, by zapewnić zgodność z protokołem o nazwie GMUCluster.. Możesz użyć warunku, aby sprawdzić, czy znacznik przekazany do modułu obsługi zdarzeń jest zgodny z tym protokołem.

Gdy już wiesz, że klaster został kliknięty, możesz wywołać funkcję animate(toZoom:) w instancji widoku mapy i ustawić powiększenie na bieżący poziom powiększenia oraz jeden. Bieżący poziom powiększenia jest dostępny w instancji mapView we właściwości camera.zoom.

Zwróć też uwagę na to, że poniższy kod zwraca true. Informuje on moduł obsługi zdarzeń, że zakończyło się jego obsługa i że nie ma już więcej kodu w module. Jednym z powodów jest to, aby uniemożliwić obiektowi GMSMarker wykonywanie pozostałej czynności domyślnej, takiej jak wyświetlanie okna informacyjnego, które nie ma sensu w przypadku kliknięcia ikony klastra.

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

Teraz ponownie załaduj aplikację, a potem kliknij kilka znaczników i klastrów znaczników. Gdy klikniesz jeden z nich, mapa zostanie wyśrodkowana na tym elemencie. Po kliknięciu klastra znaczników mapa zostanie powiększona o 1 poziom, a klaster znaczników się powiększy, pokazując znaczniki umieszczone pod spodem.

Podsumowując: w tym kroku implementujesz detektor kliknięć znaczników i przeprowadzono zdarzenie wyśrodkowania elementu klikniętego elementu i powiększysz go, jeśli ten element jest ikoną klastra znaczników.

Metoda mapView(_:didTap:) powinna wyglądać tak:

  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. Rysuj na mapie

Do tej pory udało Ci się utworzyć mapę Sydney, która pokazuje znaczniki w 100 losowych punktach i obsługuje interakcję użytkownika. W ostatnim kroku ćwiczenia z programowania użyj pakietu SDK Maps Maps na iOS, aby dodać kolejne przydatne funkcje do mapy.

Wyobraź sobie, że z tej mapy będą korzystać użytkownicy, którzy chcą poznać miasto Sydney. Przydatną funkcją jest wizualizacja promienia po kliknięciu znacznika. Dzięki temu użytkownik będzie mógł łatwo zrozumieć, jakie inne miejsca docelowe znajdują się w określonej odległości od klikniętego znacznika.

Pakiet SDK na iOS zawiera zestaw funkcji do rysowania kształtów na mapie, takich jak kwadraty, wielokąty, linie i okręgi. W tym kroku wyrenderuj okrąg, aby po kliknięciu znacznika był widoczny promień 800 metrów (około pół mili).

  1. Dodaj zmienną instancji circle do implementacji elementu ViewController.

Ta zmienna instancji służy do zapisywania ostatnio narysowanego koła, dzięki czemu można ją zniszczyć, zanim nastąpi narysowanie kolejnego. W końcu nie przypadłby do gustu użytkownikowi, nawet jeśli każdy kliknięty znacznik był otoczony kółkiem.

Aby to zrobić, zaktualizuj implementację interfejsu ViewController w ten sposób:

class ViewController: UIViewController, GMSMapViewDelegate {

  private var mapView: GMSMapView!
  private var clusterManager: GMUClusterManager!
  private var circle: GMSCircle? = nil
  ...
}
  1. Narysuj okrąg po kliknięciu znacznika.

Na dole metody mapView(_:didTap:) tuż nad instrukcją return false dodaj widoczny tutaj kod, aby utworzyć instancję klasy GMSCircle pakietu SDK na iOS, aby narysować nowy okrąg o promieniu 800 metrów, wywołując GMSCircle(position:radius:) i przenosząc go w postaci dotkniętego znacznika jak w przypadku ponownego utworzenia mapy.

    // Draw a new circle around the tapped marker
    circle = GMSCircle(position: marker.position, radius: 800)
  1. Dostosuj styl koła.

Domyślnie GMSCircle rysuje koło z czarnym pociągiem i przezroczystym wypełnieniem. Ten promień sprawdza się, ale nie wygląda zbyt dobrze i jest trochę niewidoczny. Następnie nadaj okrągowi kolor wypełnienia, by poprawić jego styl, przypisując elementowi UIColor jego właściwość fillColor. Widoczny tutaj kod dodaje szare wypełnienie z przejrzystością 50%:

    circle?.fillColor = UIColor(red: 0.67, green: 0.67, blue: 0.67, alpha: 0.5)
  1. Pokaż okrąg na mapie.

Tak jak podczas tworzenia znaczników, zdarzenie GMSCircle nie pojawi się na mapie. Aby to zrobić, przypisz instancję widoku mapy do właściwości map koła.

    circle?.map = mapView
  1. Usuń wszystkie wcześniej wyrenderowane kręgi.

Jak wspomnieliśmy wcześniej, dodawanie kręgów do mapy nie jest wygodne dla użytkowników. Aby usunąć okrąg wyrenderowany w poprzednim zdarzeniu kliknięcia, ustaw właściwość map elementu circle na nil u góry mapView(_:didTap:).

    // Clear previous circles
    circle?.map = nil

Ponownie załaduj aplikację i kliknij znacznik. Po każdym kliknięciu znacznika powinien pojawić się nowy okrąg, a wszystkie wcześniej wyrenderowane kółko zostaną usunięte, jak widać na rysunku 7.

Kółko narysowane wokół markera

Rysunek 7. Kółko narysowane wokół znacznika.

Podsumowując: w tym kroku użyto klasy GMSCircle do renderowania okręgu po każdym kliknięciu znacznika.

Metoda mapView(_:didTap:) powinna wyglądać tak:

  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. Gratulacje

Udało Ci się utworzyć aplikację na iOS z interaktywną mapą Google.

Czego się nauczysz

Co dalej?

  • Aby uzyskać więcej inspiracji, przejrzyj lub utwórz próbkę repozytorium maps-sdk-for-ios-samples z przykładami i prezentacjami
  • Dowiedz się więcej na temat kolejnych ćwiczeń z programowania Swift na temat tworzenia aplikacji na iOS za pomocą Google Maps Platform.
  • Pomóż nam utworzyć treści, które będą dla Ciebie najbardziej przydatne, odpowiadając na poniższe pytanie:

Jakie inne ćwiczenia z programowania chcesz obejrzeć?

Wizualizacja danych na mapach Więcej informacji o dostosowywaniu stylu map Tworzenie interakcji 3D w mapach

Czy ćwiczeń z programowania nie ma na liście powyżej? Tutaj możesz poprosić o nowy problem.