1. Прежде чем начать
В этой лабораторной работе вы научитесь использовать платформу Google Карт для создания приложений для iOS на Swift. Вам предстоит создать приложение для iOS, которое будет выполнять следующие функции:
- Загружает Maps SDK для iOS и библиотеку утилит Maps SDK для iOS.
- Отображает карту с центром в Сиднее, Австралия.
- Отображает пользовательские маркеры для 100 точек вокруг Сиднея.
- Реализует кластеризацию маркеров.
- Позволяет пользователю взаимодействовать с картой, центрируя ее и рисуя круг при нажатии на маркер.
Предпосылки
- Базовые знания Swift и разработки под iOS.
Что ты будешь делать?
- Загрузите Maps SDK для iOS и библиотеку утилит Google Maps SDK для iOS.
- Загрузите карту.
- Используйте маркеры, пользовательские маркеры и кластеризацию маркеров.
- Работайте с системой событий Maps SDK для iOS для поддержки взаимодействия с пользователем.
- Управляйте камерой карты программно.
- Нарисуйте на карте.
Что вам понадобится
Для выполнения этой лабораторной работы вам понадобятся следующие учетные записи, сервисы и инструменты:
- Xcode 12.0 или выше с целевым SDK 12.0 или выше.
- Cocoapods установлены.
- Учетная запись Google Cloud Platform с включенным выставлением счетов (см. следующий шаг).
- Проект в Cloud Console с включенным Maps SDK для iOS (см. следующий шаг).
2. Настройте
Для выполнения шага включения, описанного ниже, вам необходимо включить Maps SDK для iOS .
Настройте платформу Google Карт
Если у вас еще нет учетной записи Google Cloud Platform и проекта с включенным выставлением счетов, ознакомьтесь с руководством « Начало работы с Google Maps Platform», чтобы создать учетную запись для выставления счетов и проект.
- В Cloud Console щелкните раскрывающееся меню проектов и выберите проект, который вы хотите использовать для этой кодовой лаборатории.
- Включите API и SDK платформы Google Карт, необходимые для этой лабораторной работы, в Google Cloud Marketplace . Для этого следуйте инструкциям в этом видео или в этой документации .
- Сгенерируйте ключ API на странице «Учётные данные» в Cloud Console. Вы можете следовать инструкциям в этом видео или в этой документации . Для всех запросов к платформе Google Карт требуется ключ API.
Быстрый старт
Чтобы вы могли приступить к работе как можно быстрее, вот несколько начальных фрагментов кода, которые помогут вам освоить эту практическую работу.
- Клонируйте репозиторий, если у вас установлен
git
.
git clone https://github.com/googlemaps/codelab-maps-platform-101-swift.git
Или нажмите «Дайте мне код» , чтобы загрузить исходный код.
- После загрузки кода откройте проект StarterApp в каталоге
/starter
. Этот проект содержит базовую файловую структуру, необходимую для выполнения лабораторной работы. Всё необходимое для работы находится в каталоге/starter/StarterApp
.
Чтобы увидеть полный работающий код решения, просмотрите завершенный код в каталоге /solution/SolutionApp
.
3. Установите Maps SDK для iOS
Первый шаг к использованию Maps SDK для iOS — установка необходимых зависимостей. Этот процесс состоит из двух этапов: установка Maps SDK для iOS и библиотеки утилит Maps SDK для iOS из менеджера зависимостей Cocoapods, а также предоставление ключа API для SDK.
- Добавьте Maps SDK для iOS и библиотеку служебных программ Maps SDK для iOS в
Podfile
.
В этой лабораторной работе используются как Maps SDK для iOS, который предоставляет все основные функции Google Maps, так и библиотека утилит Maps iOS, которая предоставляет множество утилит для обогащения вашей карты, включая кластеризацию маркеров.
Для начала в Xcode (или предпочитаемом вами текстовом редакторе) откройте Podfile
и обновите файл, включив в него зависимости Maps SDK для iOS и Utility Library под комментарием # Pods for StarterApp
:
pod 'GoogleMaps', '6.1.0' pod 'Google-Maps-iOS-Utils', '3.4.0'
Проверьте документацию по версиям Maps SDK для 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
- Установите модули Maps SDK для iOS и Maps SDK для iOS Utility Library.
Чтобы установить зависимости, выполните команду pod install
в каталоге /starter
из командной строки. Cocoapods автоматически загрузит зависимости и создаст StarterApp.xcworkspace
.
- После установки зависимостей
open StarterApp.xcworkspace
из каталога/starter
, чтобы открыть файл в Xcode, а затем запустите приложение в симуляторе iPhone, нажавCommand+R
. Если всё настроено правильно, симулятор запустится и покажет чёрный экран. Не волнуйтесь, вы ещё ничего не собрали, так что это ожидаемо! - Импортируйте SDK в
AppDelegate.swift
.
Теперь, когда все зависимости установлены, пора предоставить ключ API для SDK. Первым шагом будет импорт Maps SDK для iOS в качестве зависимости, добавив следующее под оператором import UIKit
:
import GoogleMaps
- Передайте свой ключ API в iOS SDK, вызвав
provideAPIKey
дляGMSServices
в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
}
Ваш обновленный файл 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
на ключ API, созданный вами в Cloud Console.
Теперь, когда все зависимости установлены и предоставлен ключ API, вы готовы начать совершать вызовы к Maps SDK для iOS.
4. Отобразить карту
Пришло время показать вашу первую карту!
Наиболее часто используемой частью Maps SDK для iOS является класс GMSMapView
, который предоставляет множество методов, позволяющих создавать экземпляры карт и управлять ими. Вот как это реализовано:
- Откройте
ViewController.swift
.
Здесь вы выполните оставшуюся часть работы для этой лабораторной работы. Обратите внимание, что события жизненного цикла loadView
и viewDidLoad
для контроллера представления уже реализованы заглушками.
- Импортируйте Maps SDK для iOS, добавив следующее в начало файла:
import GoogleMaps
- Объявите переменную экземпляра
ViewController
для храненияGMSMapView
.
Экземпляр GMSMapView
— основной объект, с которым вы будете работать в этой практической работе. Вы будете ссылаться на него и работать с ним из различных методов жизненного цикла контроллера представления. Чтобы сделать его доступным, обновите реализацию ViewController
, объявив переменную экземпляра для его хранения:
class ViewController: UIViewController {
private var mapView: GMSMapView!
...
}
- В
loadView
создайте экземплярGMSCameraPosition
.
GMSCameraPosition
определяет центр карты и отображаемый уровень масштабирования. Этот код вызывает метод cameraWithLatitude:longitude:zoom:
чтобы центрировать карту на Сиднее, Австралия, с координатами широты -33,86 и долготы 151,20, с уровнем масштабирования 12:
let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 12)
- В
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
- Установите
GMSMapViewDelegate
для контроллера представления.
После реализации делегат представления карты позволяет обрабатывать события, возникающие в результате взаимодействия пользователя с экземпляром GMSMapView
, что понадобится вам позже.
Сначала обновите интерфейс ViewController
, чтобы он соответствовал протоколу GMSMapViewDelegate:
class ViewController: UIViewController, GMSMapViewDelegate
Затем добавьте следующую строку в функцию loadView
, чтобы установить GMSMapViewDelegate
для ViewController
.
mapView.delegate = self
Теперь перезагрузите приложение в симуляторе iOS ( Command+R
), и карта должна выглядеть так, как показано на следующем снимке экрана:
Рисунок 1. Приложение iOS, отображающее карту Google.
Напомним, что на этом этапе вы создали экземпляр 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. Оформите карту (необязательно)
Вы можете настроить стиль своей карты, используя облачный стиль карт .
Создать идентификатор карты
Если вы еще не создали идентификатор карты со связанным с ним стилем карты, см. руководство по идентификаторам карт , чтобы выполнить следующие шаги:
- Создайте идентификатор карты.
- Свяжите идентификатор карты со стилем карты.
Добавьте идентификатор карты в свое приложение
Чтобы использовать идентификатор карты, созданный на предыдущем шаге, откройте файл ViewController.swift
и в методе loadView
создайте объект GMSMapID
, указав ему идентификатор карты. Затем измените экземпляр GMSMapView
, передав объект GMSMapID
в качестве параметра.
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 для iOS для множества задач, но размещение маркеров на карте, безусловно, является самым популярным. Маркеры отмечают определённые точки на карте и являются распространённым элементом пользовательского интерфейса для взаимодействия с пользователем. Если вы когда-либо пользовались Google Картами, то, вероятно, знакомы с маркером по умолчанию, который выглядит как красные булавки на рисунке 2:
Рисунок 2. Карта с красными маркерами.
На этом шаге показано, как использовать класс GMSMarker
для размещения маркеров на карте.
Обратите внимание, что маркеры нельзя разместить на карте до тех пор, пока карта не будет загружена из предыдущего шага в событии жизненного цикла loadView
контроллера представления, поэтому выполните эти шаги в событии жизненного цикла viewDidLoad
, которое вызывается после загрузки представления (и карты).
- Определите объект
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)
- Создайте экземпляр
GMSMarker
.
Maps SDK для iOS предоставляет класс GMSMarker
. Каждый экземпляр GMSMarker
представляет отдельный маркер на карте и создаётся путём вызова метода markerWithPosition:
и передачи ему объекта CLLocationCoordinate2D
, который указывает SDK, где разместить маркер на карте.
let marker = GMSMarker(position: mapCenter)
- Установите пользовательский значок маркера.
Стандартный красный маркер-булавка в Google Картах — это здорово, но и настройка карты тоже хороша! К счастью, использовать собственный маркер с Maps SDK для iOS очень просто. Обратите внимание, что проект StarterApp включает изображение под названием «custom_pin.png», которое вы можете использовать, но вы можете использовать любое другое изображение.
Чтобы установить пользовательский маркер, задайте для свойства icon
маркера экземпляр UIImage
.
marker.icon = UIImage(named: "custom_pin.png")
- Отобразить маркер на карте.
Ваш маркер создан, но пока не отображается на карте. Для этого установите свойство map
экземпляра GMSMarker
на экземпляр GMSMapView
.
marker.map = mapView
Теперь перезагрузите приложение и увидьте свою первую карту с маркером, как показано на рисунке 3!
Рисунок 3. Приложение iOS с Google Картами и красным маркером в центре.
Итак, в этом разделе вы создали экземпляр класса GMSMarker и применили его к представлению карты для отображения маркера. Обновлённое событие жизненного цикла viewDidLoad в ViewController.swift
теперь должно выглядеть следующим образом:
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 Utility Library, которая, помимо прочего, автоматически выполняет кластеризацию маркеров. Подробнее о кластеризации маркеров читайте в документации платформы Google Карт или ознакомьтесь с исходным кодом библиотеки iOS Utility Library на GitHub .
- Добавьте больше маркеров на карту.
Чтобы увидеть кластеризацию маркеров в действии, вам потребуется много маркеров на карте. Для оптимизации процесса используйте генератор маркеров, предоставленный в стартовом проекте MarkerGenerator.swift
.
Чтобы добавить на карту заданное количество маркеров, вызовите MarkerGenerator(near:count:).markerArray
в жизненном цикле viewDidLoad
контроллера представления, расположенном под кодом из предыдущего шага. Этот метод создаёт маркеры в указанном в count
в случайных точках вокруг координат, указанных в объекте CLLocationCoordinate2D
. В этом случае вы можете передать ему созданную ранее переменную mapCenter
. Маркеры возвращаются в объекте [GMSMarker]
.
// Generate many markers
let markerArray = MarkerGenerator(near: mapCenter, count: 100).markerArray
Вы можете проверить, как выглядит такое количество маркеров, добавив следующие строки после определения markerArray
и запустив приложение. Обязательно закомментируйте эти строки, прежде чем переходить к следующим шагам, где для управления отображением маркеров используется Marker Clusterer:
// Comment the following code out if using the marker clusterer
// to manage markers instead.
for marker in markerArray {
marker.map = mapView
}
- Импортируйте библиотеку утилит Google Maps SDK для iOS.
Чтобы добавить библиотеку утилиты Maps iOS в качестве зависимости к вашему проекту, добавьте это в список зависимостей в верхней части ViewController.swift
:
import GoogleMapsUtils
- Настройте кластеризатор маркеров.
Чтобы использовать кластеризатор маркеров, необходимо настроить три параметра: алгоритм кластеризации, генератор значков и рендерер. Алгоритм определяет поведение кластеризации маркеров, например, расстояние между маркерами, включаемыми в один кластер. Генератор значков предоставляет значки кластеров для использования на разных уровнях масштабирования. Рендерер отвечает за рендеринг значков кластеров на карте.
При желании вы можете написать всё это с нуля. Кроме того, библиотека 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)
- Создайте экземпляр
GMUClusterManager
.
GMUClusterManager
— это класс, реализующий кластеризацию маркеров с использованием указанного вами алгоритма, генератора значков и рендерера. Чтобы создать рендерер и сделать его доступным для представления карты, сначала добавьте переменную экземпляра в реализацию ViewController
для хранения экземпляра менеджера кластера:
class ViewController: UIViewController, GMSMapViewDelegate {
private var mapView: GMSMapView!
private var clusterManager: GMUClusterManager!
}
Затем создайте экземпляр GMUClusterManager
в событии жизненного цикла viewDidLoad
:
clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
- Добавьте маркеры и запустите кластеризатор маркеров.
Теперь, когда экземпляр кластеризатора маркеров настроен, передайте диспетчеру кластера массив маркеров, которые нужно кластеризовать, вызвав add(items:)
, а затем запустите кластеризатор, вызвав cluster
.
clusterManager.setMapDelegate(self)
clusterManager.add(markerArray)
clusterManager.cluster()
Перезагрузите приложение, и теперь вы увидите множество маркеров, аккуратно сгруппированных, как показано на рисунке 6. Продолжайте экспериментировать с различными уровнями масштабирования, изменяя масштаб карты и сводя/разводя пальцы, чтобы увидеть, как кластеры маркеров адаптируются по мере увеличения/уменьшения масштаба.
Рисунок 6. Приложение iOS с Google Maps и сгруппированными маркерами.
Итак, на этом шаге вы настроили экземпляр кластеризатора маркеров из библиотеки утилит Google Maps SDK для iOS, а затем использовали его для кластеризации 100 маркеров на карте. Событие жизненного цикла viewDidLoad
в ViewController.swift
теперь должно выглядеть так:
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 для iOS предоставляет комплексную систему событий, реализованную через делегат вида карты, который включает обработчики событий, позволяющие выполнять код при различных взаимодействиях пользователя. Например, делегат MapView включает методы, позволяющие инициировать выполнение кода при таких взаимодействиях, как нажатие пользователем на карту и маркеры, панорамирование карты, увеличение и уменьшение масштаба и т. д.
На этом этапе вы программно перемещаете карту в центр относительно любого маркера, на который нажимает пользователь.
- Реализуйте прослушиватель нажатий маркера.
mapView(_:didTap:)
вызывается каждый раз, когда пользователь нажимает на один из маркеров, созданных вами ранее, и каждый раз, когда пользователь нажимает на кластер маркеров (внутренне кластеры маркеров реализованы как экземпляр GMSMarker
).
Чтобы реализовать прослушиватель событий, начните с его добавления заглушки в конец ViewController.swift
перед закрывающейся фигурной скобкой.
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
return false
}
Обратите внимание, что метод возвращает false
. Это указывает iOS SDK на необходимость продолжить выполнение стандартного поведения GMSMarker
, например, отображать информационное окно , если оно настроено, после выполнения кода обработчика событий.
- Обрабатывайте событие нажатия и анимируйте камеру для центрирования карты при нажатии маркера или группы маркеров.
При вызове mapView(_:didTap:)
передаёт экземпляр GMSMarker
, к которому был прикоснулся пользователь, чтобы вы могли обработать его в своём коде. Вы можете использовать этот экземпляр для центрирования карты, вызвав animate(toLocation:)
для представления карты из обработчика событий и передав ему положение экземпляра маркера из свойства position
.
// Animate to the marker
mapView.animate(toLocation: marker.position)
- При нажатии на кластер маркеров увеличьте его масштаб.
Распространенный UX-шаблон — увеличение масштаба кластеров маркеров при нажатии на них. Это позволяет пользователям видеть кластеры маркеров, поскольку кластер увеличивается при уменьшении масштаба.
Как отмечалось ранее, значок кластера маркеров фактически представляет собой реализацию GMSMarker
с пользовательским значком. Как же определить, был ли нажат маркер или кластер маркеров? Когда менеджер кластеризации маркеров создаёт новый значок кластера, он реализует экземпляр GMSMarker
для соответствия протоколу GMUCluster.
Вы можете использовать условие для проверки соответствия маркера, переданного в обработчик событий, этому протоколу.
Как только вы программно определили, что кластер был использован, вы можете вызвать animate(toZoom:)
для экземпляра представления карты и установить масштаб, равный текущему уровню масштабирования плюс один. Текущий уровень масштабирования доступен для экземпляра mapView в свойстве camera.zoom
.
Также обратите внимание, как следующий код возвращает 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 для iOS, чтобы добавить дополнительную полезную функцию к вашему опыту работы с картой.
Представьте, что эта карта будет использоваться пользователями, желающими исследовать Сидней. Полезной функцией было бы отображение радиуса вокруг маркера при щелчке по нему. Это позволило бы пользователю быстро понять, какие ещё места находятся в непосредственной близости от выбранного маркера.
iOS SDK включает набор функций для рисования фигур на карте, таких как квадраты, многоугольники, линии и круги. На этом этапе отрисовываем круг, отображающий область радиусом 800 метров (примерно полмили) вокруг маркера при щелчке по нему.
- Добавьте переменную экземпляра
circle
в реализацию ViewController.
Эта переменная экземпляра используется для сохранения последнего нарисованного круга, чтобы его можно было уничтожить до того, как будет нарисован другой. В конце концов, это было бы не очень полезно для пользователя и выглядело бы некрасиво, если бы каждый нажатый маркер был обведён кругом!
Для этого обновите реализацию ViewController
следующим образом:
class ViewController: UIViewController, GMSMapViewDelegate {
private var mapView: GMSMapView!
private var clusterManager: GMUClusterManager!
private var circle: GMSCircle? = nil
...
}
- При нажатии на маркер нарисуйте круг.
В нижней части метода mapView(_:didTap:)
прямо над оператором return false
добавьте показанный здесь код для создания экземпляра класса GMSCircle
из iOS SDK для рисования нового круга радиусом 800 метров путем вызова GMSCircle(position:radius:)
и передачи ему позиции нажатого маркера, как вы это делали при центрировании карты.
// Draw a new circle around the tapped marker
circle = GMSCircle(position: marker.position, radius: 800)
- Оформите круг.
По умолчанию GMSCircle
рисует круг с чёрной обводкой и прозрачной заливкой. Этого достаточно для отображения радиуса, но выглядит он не очень хорошо и немного плохо различим. Затем задайте кругу цвет заливки, чтобы улучшить его стилистику, назначив UIColor
свойству fillColor
круга. Приведённый здесь код добавляет серую заливку с прозрачностью 50%.
circle?.fillColor = UIColor(red: 0.67, green: 0.67, blue: 0.67, alpha: 0.5)
- Нарисуйте круг на карте.
Как и при создании маркеров ранее, создание экземпляра GMSCircle
не приводит к его отображению на карте. Для этого назначьте экземпляр представления карты свойству map
круга.
circle?.map = mapView
- Удалите все ранее нарисованные круги.
Как уже отмечалось, постоянное добавление кругов на карту было бы не очень удобным для пользователя. Чтобы удалить круг, отрисованный предыдущим касанием, установите свойство map
circle
в nil
в верхней части mapView(_:didTap:)
.
// 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 для iOS и библиотеки служебных программ Google Maps SDK для iOS
- Загрузка карты
- Стилизация карты
- Использование маркеров , пользовательских маркеров и кластеризации маркеров
- Система событий для обеспечения взаимодействия с пользователем
- Программное управление камерой карты
- Рисунок на карте
Что дальше?
- Исследуйте или создайте форк репозитория
maps-sdk-for-ios-samples
на GitHub с примерами и демонстрациями для большего вдохновения. - Ознакомьтесь с дополнительными практическими руководствами по написанию кода Swift для создания приложений iOS с использованием платформы Google Maps
- Помогите нам создать контент, который будет вам наиболее полезен, ответив на следующий опрос:
Какие еще практические занятия вы хотели бы увидеть?
Не нашли нужную вам практическую работу? Запросите её в новом выпуске здесь .