Добавьте карту в свое приложение iOS (Objective-C)

1. Прежде чем начать

Абстрактный

В этой лабораторной работе вы узнаете всё необходимое для начала работы с платформой Google Карт для создания приложений iOS на Objective-C. Вы изучите все основы: от настройки до загрузки Maps SDK для iOS, отображения вашей первой карты, работы с маркерами и кластеризацией маркеров, рисования на карте и обработки взаимодействия с пользователем.

Что вы построите

342520482a888519.png

В этой лабораторной работе вы создадите приложение для iOS, которое будет выполнять следующие функции:

  • Загружает Maps SDK для iOS и библиотеку служебных программ Maps SDK для iOS.
  • Отображает карту с центром в Сиднее, Австралия.
  • Отображает пользовательские маркеры для 100 точек вокруг Сиднея.
  • Реализует кластеризацию маркеров
  • Позволяет пользователю взаимодействовать с картой, центрируя ее и рисуя круг при нажатии на маркер.

Чему вы научитесь

  • Начало работы с платформой Google Карт
  • Загрузка Maps SDK для iOS и библиотеки служебных программ Google Maps SDK для iOS
  • Загрузка карты
  • Использование маркеров, пользовательских маркеров и кластеризации маркеров
  • Работа с системой событий Maps SDK для iOS для обеспечения взаимодействия с пользователем
  • Программное управление картой
  • Рисунок на карте

Предпосылки

Для выполнения этой практической работы вам потребуется ознакомиться с приведенными ниже пунктами. Если вы уже знакомы с платформой Google Карт, перейдите сразу к практической работе!

Необходимые продукты платформы Google Карт

В этой лабораторной работе вы будете использовать следующие продукты платформы Google Maps:

  • Карт SDK для iOS
  • Библиотека утилит Google Maps SDK для iOS

Начните работу с платформой Google Карт

Если вы ранее не использовали платформу Google Карт, следуйте руководству «Начало работы с платформой Google Карт» или посмотрите плейлист «Начало работы с платформой Google Карт», чтобы выполнить следующие шаги:

  1. Создайте платежный аккаунт.
  2. Создать проект.
  3. Включите API и SDK платформы Google Карт (перечислены в предыдущем разделе).
  4. Сгенерируйте ключ API.

Другие требования для этой лабораторной работы

Для выполнения этой лабораторной работы вам понадобятся следующие учетные записи, сервисы и инструменты:

  • Учетная запись Google Cloud Platform с включенным выставлением счетов
  • Ключ API платформы Google Карт с включенным Maps SDK для iOS
  • Базовые знания Objective-C
  • Xcode 12.0 с целевым SDK 12.0 или более поздней версии

2. Настройте

Для выполнения шага включения, описанного ниже, вам потребуется включить Maps SDK для iOS .

Настройте платформу Google Карт

Если у вас еще нет учетной записи Google Cloud Platform и проекта с включенным выставлением счетов, ознакомьтесь с руководством « Начало работы с Google Maps Platform», чтобы создать учетную запись для выставления счетов и проект.

  1. В Cloud Console щелкните раскрывающееся меню проектов и выберите проект, который вы хотите использовать для этой кодовой лаборатории.

  1. Включите API и SDK платформы Google Карт, необходимые для этой лабораторной работы, в Google Cloud Marketplace . Для этого следуйте инструкциям в этом видео или в этой документации .
  2. Сгенерируйте ключ API на странице «Учётные данные» в Cloud Console. Вы можете следовать инструкциям в этом видео или в этой документации . Для всех запросов к платформе Google Карт требуется ключ API.

Настройка шаблона Project Starter

Прежде чем приступить к работе над этой лабораторной работой, выполните следующие действия, чтобы загрузить шаблон начального проекта, а также полный код решения:

  1. Загрузите или сделайте форк репозитория GitHub для этой лабораторной работы по адресу https://github.com/googlecodelabs/maps-platform-101-objc .

Проект StarterApp находится в каталоге /starter и включает в себя базовую файловую структуру, необходимую для выполнения лабораторной работы. Всё необходимое для работы находится в каталоге /starter/StarterApp .

Если вы хотите увидеть полный работающий код решения, вы можете выполнить описанные выше шаги по настройке и просмотреть решение в каталоге /solution/SolutionApp .

3. Установите Maps SDK для iOS

Первый шаг к использованию Maps SDK для iOS — установка необходимых зависимостей. Этот процесс состоит из двух этапов: установка Maps SDK для iOS и библиотеки утилит Maps SDK для iOS из менеджера зависимостей Cocoapods, а также предоставление ключа API для SDK.

  1. Добавьте Maps SDK для iOS и библиотеку служебных программ Maps SDK для iOS в Podfile .

В этой лабораторной работе вы будете использовать как Maps SDK для iOS, который предоставляет все основные функции Google Maps, так и библиотеку утилит Maps iOS, которая содержит множество утилит для обогащения вашей карты, включая кластеризацию маркеров.

Для начала в Xcode (или предпочитаемом вами текстовом редакторе) откройте Pods > Podfile и обновите файл, включив в него зависимости Maps SDK for iOS и Utility Library в use_frameworks!

pod 'GoogleMaps'
pod 'Google-Maps-iOS-Utils'
  1. Установите модули Maps SDK для iOS и Maps SDK для iOS Utility Library.

Чтобы установить зависимости, выполните команду pod install в каталоге /starter из командной строки. Cocoapods автоматически загрузит зависимости и создаст StarterApp.xcworkspace . 3. После установки зависимостей откройте StarterApp.xcworkspace в Xcode, а затем запустите приложение в симуляторе iPhone, нажав Command+R . Если всё настроено правильно, симулятор запустится и покажет чёрный экран. Не волнуйтесь, вы ещё ничего не собрали, так что это ожидаемо! 4. Импортируйте SDK в AppDelegate.h .

Теперь, когда все зависимости установлены, пора предоставить ключ API для SDK. Первым шагом будет импорт Maps SDK для iOS как зависимости, добавив следующий код под оператором импорта #import "AppDelegate.h" :

@import GoogleMaps;
  1. Под оператором импорта iOS SDK объявите константу NSString со значением, равным вашему ключу API:
static NSString *const kMapsAPIKey = @"YOUR API KEY";
  1. Передайте ключ API в iOS SDK, вызвав provideAPIKey для GMSServices в application: didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GMSServices provideAPIKey:kMapsAPIKey];
  return YES;
}

Теперь ваш обновленный файл AppDelegate.m должен выглядеть так:

#import "AppDelegate.h"
@import GoogleMaps;

static NSString *const kMapsAPIKey = @"YOUR API KEY";

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [GMSServices provideAPIKey:kMapsAPIKey];
  return YES;
}
@end

Ваш Podfile должен выглядеть так:

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

target 'StarterApp' do
  use_frameworks!

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

end

Теперь, когда все зависимости установлены и предоставлен ключ API, вы готовы начать совершать вызовы к Maps SDK для iOS.

4. Отобразить карту

Пришло время показать вашу первую карту!

Наиболее часто используемой частью Maps SDK для iOS является класс GMSMapView , который предоставляет множество методов, позволяющих создавать экземпляры карт и управлять ими. Вот как это реализовано.

  1. Откройте ViewController.m .

Здесь вы будете выполнять всю оставшуюся работу для этой лабораторной работы. Вы заметите, что события жизненного цикла loadView и viewDidLoad для контроллера представления уже защищены заглушками. 2. Импортируйте Maps SDK для iOS, добавив следующее в начало файла:

@import GoogleMaps;
  1. Объявите переменную экземпляра ViewController для хранения GMSMapView .

Экземпляр GMSMapView — это основной объект, с которым вы будете работать в этой лабораторной работе. Вы будете ссылаться на него и работать с ним из различных методов жизненного цикла контроллера представления. Чтобы сделать его доступным, обновите реализацию ViewController , объявив переменную экземпляра для его хранения:

@implementation ViewController {
  GMSMapView *_mapView;
}
  1. В loadView создайте экземпляр GMSCameraPosition .

GMSCameraPosition определяет, где будет центрирована карта и какой уровень масштабирования она будет отображать. Этот код вызывает метод cameraWithLatitude:longitude:zoom: чтобы центрировать карту на Сиднее, Австралия, с координатами широты -33,86 и долготы 151,20, с уровнем масштабирования 12:

GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86 longitude:151.20 zoom:12];
  1. В loadView создайте экземпляр GMSMapView для создания карты.

Чтобы создать новый экземпляр карты, вызовите mapWithFrame:camera: . Обратите внимание, что фрейму присваивается значение CGRectZero , глобальной переменной из библиотеки iOS CGGeometry , которая задаёт фрейм шириной 0 и высотой 0, расположенный в позиции (0,0) внутри контроллера представления. Камера устанавливается в только что созданное вами положение.

Чтобы отобразить карту, вам нужно установить корневое представление контроллера представления на _mapview , что позволит отображать карту на весь экран.

_mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
self.view = _mapView;
  1. Установите GMSMapViewDelegate для контроллера представления.

После реализации делегат представления карты позволяет обрабатывать события, возникающие в результате взаимодействия пользователя с экземпляром GMSMapView , что понадобятся вам на последующих этапах.

Сначала обновите интерфейс ViewController , чтобы он соответствовал протоколу GMSMapViewDelegate:

@interface ViewController ()<GMSMapViewDelegate>

Затем добавьте следующее, чтобы установить GMSMapViewDelegate для ViewController .

_mapView.delegate = self;

Теперь перезагрузите приложение в симуляторе iOS ( Command+R ), и карта должна появиться!

2e6ebac422323aa6.png

Напомним, что на этом этапе вы создали экземпляр GMSMapView для отображения карты с центром в городе Сидней, Австралия.

Теперь ваш файл ViewController.m должен выглядеть так:

#import "ViewController.h"
#import "LocationGenerator.h"
@import GoogleMaps;

@interface ViewController ()<GMSMapViewDelegate>
@end

@implementation ViewController {
  GMSMapView *_mapView;
}

- (void)loadView {
  [super loadView];
  GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86 longitude:151.20 zoom:12];
  _mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
  self.view = _mapView;
  _mapView.delegate = self;
}

5. Облачная стилизация карты (необязательно)

Вы можете настроить стиль своей карты, используя облачный стиль карт .

Создать идентификатор карты

Если вы еще не создали идентификатор карты со связанным с ним стилем карты, см. руководство по идентификаторам карт , чтобы выполнить следующие шаги:

  1. Создайте идентификатор карты.
  2. Свяжите идентификатор карты со стилем карты.

Добавление идентификатора карты в ваше приложение

Чтобы использовать идентификатор карты, созданный на предыдущем шаге, откройте файл ViewController.m и в методе loadView создайте объект GMSMapID и передайте ему идентификатор карты. Затем измените экземпляр GMSMapView , передав объект GMSMapID в качестве параметра.

ViewController.m

- (void)loadView {
    GMSMapID *mapID = [[GMSMapID alloc] initWithIdentifier:@"YOUR_MAP_ID"];
    _mapView = [GMSMapView mapWithFrame:CGRectZero mapID:mapID camera:camera];
    // ...
}

После того как вы это сделаете, запустите приложение, чтобы увидеть карту в выбранном вами стиле!

6. Добавьте маркеры на карту

Разработчики используют Maps SDK для iOS для множества задач, но размещение маркеров на карте, безусловно, является самым популярным. Маркеры позволяют отображать определённые точки на карте и являются распространённым элементом пользовательского интерфейса для взаимодействия с пользователем. Если вы уже пользовались Google Картами, то, вероятно, знакомы с маркером по умолчанию, который выглядит так:

590815267846f166.png

На этом этапе вы узнаете, как использовать класс GMSMarker для размещения маркеров на карте.

Обратите внимание, что маркеры не могут быть размещены на карте до тех пор, пока карта не будет загружена из предыдущего шага в событии жизненного цикла loadView контроллера представления, поэтому вы выполните эти шаги в событии жизненного цикла viewDidLoad , которое вызывается после загрузки представления (и карты).

  1. Определите объект CLLocationCoordinate2D .

CLLocationCoordinate2D — это структура, доступная в библиотеке iOS CoreLocation , которая определяет географическое местоположение с заданными широтой и долготой. Чтобы начать создавать свой первый маркер, определите объект CLLocationCoordinate2D и задайте широту и долготу центра карты. Координаты центра карты можно получить из представления карты, используя свойства camera.target.latitude и camera.target.longitude .

CLLocationCoordinate2D mapCenter = CLLocationCoordinate2DMake(_mapView.camera.target.latitude, _mapView.camera.target.longitude);
  1. Создайте экземпляр GMSMarker .

Maps SDK для iOS предоставляет класс GMSMarker . Каждый экземпляр GMSMarker представляет отдельный маркер на карте и создаётся путём вызова метода markerWithPosition: и передачи ему объекта CLLocationCoordinate2D , который указывает SDK, где разместить маркер на карте .

GMSMarker *marker = [GMSMarker markerWithPosition:mapCenter];
  1. Установите пользовательский значок маркера.

Стандартный красный маркер-булавка для Google Карт — это здорово, но и настроить карту тоже! К счастью, использовать собственный маркер очень просто с Maps SDK для iOS. Вы заметите, что проект StarterApp включает изображение под названием custom_pin.png, которое вы можете использовать, но вы можете использовать любое другое изображение.

Чтобы установить пользовательский маркер, задайте для свойства icon маркера экземпляр UIImage .

marker.icon = [UIImage imageNamed:@"custom_pin.png"];
  1. Отобразить маркер на карте.

Маркер создан, но вы заметите, что его нет на карте. Для этого установите свойство map экземпляра GMSMarker на экземпляр GMSMapView .

marker.map = _mapView;

Теперь перезагрузите приложение и посмотрите на свою первую карту с маркером!

a4ea8724f8c5ba20.png

Итак, в этом разделе вы создали экземпляр класса GMSMarker и применили его к представлению карты для отображения маркера. Обновлённое событие жизненного цикла viewDidLoad в ViewController.m теперь должно выглядеть следующим образом:

- (void)viewDidLoad {
  [super viewDidLoad];

  CLLocationCoordinate2D mapCenter = CLLocationCoordinate2DMake(_mapView.camera.target.latitude, _mapView.camera.target.longitude);
  GMSMarker *marker = [GMSMarker markerWithPosition:mapCenter];
  marker.icon = [UIImage imageNamed:@"custom_pin.png"];
  marker.map = _mapView;
}

7. Включить кластеризацию маркеров

При использовании большого количества маркеров или маркеров, расположенных близко друг к другу, может возникнуть проблема, когда маркеры будут перекрываться или казаться слишком скученными, что создаст неудобства для пользователя. Например, если два маркера расположены очень близко друг к другу, может возникнуть следующая ситуация:

6e39736160c6bce4.png

Вот тут-то и пригодится кластеризация маркеров. Кластеризация маркеров — еще одна часто реализуемая функция, которая группирует близлежащие маркеры в один значок, который меняется в зависимости от уровня масштабирования, вот так:

4abb38cd97cab3f1.png

Алгоритм кластеризации маркеров разбивает видимую область карты на сетку, а затем группирует значки, находящиеся в одной ячейке. К счастью, вам не нужно беспокоиться об этом, поскольку команда платформы Google Карт создала полезную библиотеку с открытым исходным кодом под названием Google Maps SDK for iOS Utility Library. Эта библиотека, помимо прочего, автоматически выполняет кластеризацию маркеров. Подробнее о кластеризации маркеров можно узнать в документации платформы Google Карт или ознакомиться с исходным кодом библиотеки iOS Utility Library на GitHub .

  1. Добавьте на карту гораздо больше маркеров.

Чтобы увидеть кластеризацию маркеров в действии, вам потребуется много маркеров на карте. Для этого в стартовом проекте LocationGenerator.m предусмотрен удобный генератор маркеров.

Чтобы добавить на карту необходимое количество маркеров, просто вызовите метод generateMarkersNear:count: в жизненном цикле viewDidLoad контроллера представления, расположенном под кодом из предыдущего шага. Этот метод создаёт маркеры в указанном в count количестве в случайных точках вокруг координат, указанных в объекте CLLocationCoordinate2D . В этом случае вы можете просто передать ему созданную ранее переменную mapCenter . Маркеры возвращаются в NSArray .

NSArray<GMSMarker *> *markerArray = [LocationGenerator generateMarkersNear:mapCenter count:100];
  1. Импортируйте библиотеку утилит Google Maps SDK для iOS.

Чтобы добавить библиотеку утилит Maps iOS в качестве зависимости к вашему проекту, добавьте следующее в список зависимостей в верхней части ViewController.m :

@import GoogleMapsUtils;
  1. Настройте кластеризатор маркеров.

Чтобы использовать кластеризатор маркеров, необходимо настроить три параметра: алгоритм кластеризации, генератор значков и рендерер. Алгоритм определяет поведение кластеризации маркеров, например, расстояние между маркерами, включаемыми в один кластер. Генератор значков предоставляет значки кластеров для использования на разных уровнях масштабирования. Рендерер отвечает за рендеринг значков кластеров на карте.

При желании вы можете написать всё это с нуля, но библиотека Maps для iOS предоставляет готовые реализации по умолчанию, упрощающие процесс. Просто добавьте следующее:

id<GMUClusterAlgorithm> algorithm = [[GMUNonHierarchicalDistanceBasedAlgorithm alloc] init];

id<GMUClusterIconGenerator> clusterIconGenerator = [[GMUDefaultClusterIconGenerator alloc] init];

id<GMUClusterRenderer> renderer = [[GMUDefaultClusterRenderer alloc] initWithMapView:_mapView clusterIconGenerator:clusterIconGenerator];
  1. Создайте экземпляр GMUClusterManager .

GMUClusterManager — это класс, реализующий кластеризацию маркеров, используя заданные вами алгоритм, генератор значков и рендерер. Чтобы создать рендерер и сделать его доступным для представления карты, сначала добавьте переменную экземпляра в реализацию ViewController для хранения экземпляра менеджера кластера:

@implementation ViewController {
  GMSMapView *_mapView;
  GMUClusterManager *_clusterManager;
}

Затем создайте экземпляр GMUClusterManager в событии жизненного цикла viewDidLoad :

_clusterManager = [[GMUClusterManager alloc] initWithMap:_mapView algorithm:algorithm renderer:renderer];
  1. Добавьте маркеры и запустите кластеризатор маркеров.

Теперь, когда экземпляр кластеризатора маркеров настроен, все, что вам нужно сделать, это передать диспетчеру кластера массив маркеров, которые нужно кластеризовать, вызвав addItems: а затем запустить кластеризатор, вызвав cluster .

[_clusterManager addItems:markerArray];
[_clusterManager cluster];

Перезагрузите приложение, и вы увидите множество маркеров, аккуратно сгруппированных. Поэкспериментируйте с разными уровнями масштабирования, изменяя масштаб карты, и посмотрите, как скопления маркеров адаптируются к масштабу.

c49383b07752bfc4.png

Итак, на этом шаге вы настроили экземпляр кластеризатора маркеров из библиотеки утилит Google Maps SDK для iOS, а затем использовали его для кластеризации 100 маркеров на карте. Событие жизненного цикла viewDidLoad в ViewController.m теперь должно выглядеть так:

- (void)viewDidLoad {
  [super viewDidLoad];

  CLLocationCoordinate2D mapCenter = CLLocationCoordinate2DMake(_mapView.camera.target.latitude,
                                                                _mapView.camera.target.longitude);
  GMSMarker *marker = [GMSMarker markerWithPosition:mapCenter];
  marker.icon = [UIImage imageNamed:@"custom_pin.png"];
  marker.map = _mapView;
  NSArray<GMSMarker *> *markerArray = [LocationGenerator generateMarkersNear:mapCenter count:100];

  id<GMUClusterAlgorithm> algorithm = [[GMUNonHierarchicalDistanceBasedAlgorithm alloc] init];
  id<GMUClusterIconGenerator> clusterIconGenerator = [[GMUDefaultClusterIconGenerator alloc] init];
  id<GMUClusterRenderer> renderer = [[GMUDefaultClusterRenderer alloc] initWithMapView:_mapView clusterIconGenerator:clusterIconGenerator];
  _clusterManager = [[GMUClusterManager alloc] initWithMap:_mapView algorithm:algorithm renderer:renderer];

  [_clusterManager addItems:markerArray];
  [_clusterManager cluster];
}

8. Добавьте взаимодействие с пользователем

Теперь у вас есть отличная карта с маркерами и кластеризацией маркеров. На этом этапе вы добавите дополнительную обработку пользовательских взаимодействий с помощью GMSMapViewDelegate , который вы ранее установили для контроллера представления, чтобы улучшить пользовательский опыт использования вашей карты.

Maps SDK для iOS предоставляет комплексную систему событий, реализованную через делегат вида карты, который включает обработчики событий, позволяющие выполнять код при различных взаимодействиях пользователя. Например, делегат вида карты включает методы, позволяющие инициировать выполнение кода при таких взаимодействиях, как нажатие пользователем на карту и маркеры, панорамирование карты, увеличение и уменьшение масштаба и т. д.

На этом этапе вы программно сделаете так, чтобы карта центрировалась на любом маркере, которого коснется пользователь.

  1. Реализуйте прослушиватель нажатий маркера.

mapView:didTapMarker вызывается каждый раз, когда пользователь нажимает на один из маркеров, созданных вами ранее, а также каждый раз, когда пользователь нажимает на кластер маркеров (внутренне кластеры маркеров реализованы как экземпляр GMSMarker ).

Чтобы реализовать прослушиватель событий, начните с его добавления заглушки в конец ViewController.m перед оператором end .

Обратите внимание, что метод возвращает NO . Это указывает iOS SDK продолжить выполнение стандартных функций GMSMarker , таких как отображение информационного окна , если оно настроено, после выполнения кода обработчика событий.

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {

  return NO;
}
  1. Обрабатывайте событие нажатия и анимируйте камеру для центрирования карты при нажатии маркера или группы маркеров.

При вызове mapView:didTapMarker передаёт экземпляр GMSMarker , который был нажат, что позволяет обрабатывать его в коде. Вы можете использовать этот экземпляр для центрирования карты, вызвав animateToLocation: в представлении карты из обработчика событий и передав ему позицию экземпляра маркера, доступную в свойстве position .

[_mapView animateToLocation:marker.position];
  1. При нажатии на кластер маркеров увеличьте его масштаб.

Распространенный UX-шаблон — увеличение масштаба кластеров маркеров при нажатии на них. Это позволяет пользователям видеть кластеры маркеров, поскольку кластер будет увеличиваться при более низком уровне масштабирования.

Как отмечалось ранее, значок кластера маркеров — это, по сути, реализация GMSMarker с пользовательским значком. Как же определить, был ли нажат маркер или кластер маркеров? Когда менеджер кластеризации маркеров создаёт новый значок кластера, он реализует экземпляр GMSMarker для соответствия протоколу GMUCluster. Вы можете использовать условие для проверки соответствия маркера, переданного в обработчик событий, этому протоколу.

После того, как вы программно определили, что кластер был задействован, вы можете вызвать animateToZoom: в экземпляре представления карты и установить масштаб, равный текущему уровню масштабирования плюс один. Текущий уровень масштабирования доступен в экземпляре представления карты в свойстве camera.zoom .

Также обратите внимание, как код ниже возвращает значение YES . Это сообщает обработчику событий, что обработка события завершена, и не требует выполнения дальнейшего кода в обработчике. Одна из причин этого — предотвратить выполнение базовым объектом GMSMarker оставшейся части его стандартного поведения, например, отображения информационного окна, что было бы бессмысленно в случае нажатия на значок кластера.

if ([marker.userData conformsToProtocol:@protocol(GMUCluster)]) {
    [_mapView animateToZoom:_mapView.camera.zoom +1];
    return YES;
}

Теперь перезагрузите приложение и коснитесь маркеров и кластеров маркеров. При касании любого из них карта центрируется на выбранном элементе. При касании кластера маркеров масштаб карты также увеличивается на один уровень, а кластер маркеров расширяется, отображая маркеры, расположенные под ним.

Подведем итог: на этом этапе вы реализовали прослушиватель касания маркера и обработали событие для центрирования нажатого элемента и увеличения масштаба, если этот элемент является значком кластера маркеров.

Ваш метод mapView:didTapMarker должен выглядеть так:

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
  [_mapView animateToLocation:marker.position];

  if ([marker.userData conformsToProtocol:@protocol(GMUCluster)]) {
    [_mapView animateToZoom:_mapView.camera.zoom +1];
    return YES;
  }

  return NO;
}

9. Нарисуйте на карте

На данный момент вы создали карту Сиднея с маркерами в 100 случайных точках и обрабатываем взаимодействие с пользователем. На последнем этапе этой лабораторной работы вы будете использовать функции рисования Maps SDK для iOS, чтобы добавить дополнительную полезную функцию к своей карте.

Представьте, что эта карта будет использоваться пользователями, желающими исследовать Сидней. Полезной функцией было бы визуализировать радиус вокруг маркера при нажатии на него. Это позволило бы пользователю легко понять, какие ещё места находятся в пешей доступности от выбранного маркера.

iOS SDK включает набор функций для рисования фигур на карте, таких как квадраты, многоугольники, линии и круги. Далее вам нужно отобразить круг, отображающий радиус 800 метров (примерно полмили) вокруг маркера при щелчке по нему.

  1. Добавьте переменную экземпляра _circ в реализацию ViewController.

Эта переменная экземпляра будет использоваться для сохранения последнего нарисованного круга, чтобы его можно было уничтожить перед нарисовкой следующего. В конце концов, это было бы не очень полезно для пользователя и выглядело бы довольно некрасиво, если бы каждый нажатый маркер был обведён кругом!

Для этого обновите реализацию ViewController следующим образом:

@implementation ViewController {
  GMSMapView *_mapView;
  GMUClusterManager *_clusterManager;
  GMSCircle *_circ;
}
  1. При нажатии на маркер нарисуйте круг.

В нижней части метода mapView:didTapMarker добавьте следующий код для создания экземпляра класса GMSCircle из iOS SDK, чтобы нарисовать новый круг радиусом 800 метров, вызвав circleWithPosition:radius: и передав ему позицию нажатого маркера, как вы делали выше, когда центрировали карту.

_circ = [GMSCircle circleWithPosition:marker.position radius:800];
  1. Оформите круг.

По умолчанию GMSCircle рисует круг с чёрной обводкой и прозрачной заливкой. Этого хватит для отображения радиуса, но выглядит не очень хорошо и немного нечётко. Затем задайте кругу цвет заливки, чтобы улучшить его стилистику, назначив UIColor свойству fillColor круга. Следующий код добавит серую заливку с прозрачностью 50%.

_circ.fillColor = [UIColor colorWithRed: 0.67 green: 0.67 blue: 0.67 alpha: 0.5];
  1. Нарисуйте круг на карте.

Как и при создании маркеров ранее, вы заметите, что простое создание экземпляра GMSCircle не приводит к его появлению на карте. Для этого просто назначьте экземпляр представления карты свойству map круга.

_circ.map = _mapView;
  1. Удалите все ранее нарисованные круги.

Как уже отмечалось, простое добавление кругов на карту было бы не очень удобным для пользователя. Чтобы удалить круг, отрисованный предыдущим касанием, установите свойство map _circ в nil в верхней части mapView:didTapMarker .

_circ.map = nil;

Перезагрузите приложение и коснитесь маркера. При каждом касании маркера должен появиться новый круг, а все ранее отображённые круги должны быть удалены.

342520482a888519.png

Напомним, что на этом этапе вы использовали класс GMSCircle для визуализации круга при каждом касании маркера.

Метод mapView:didTapMarker должен выглядеть так:

- (BOOL)mapView:(GMSMapView *)mapView didTapMarker:(GMSMarker *)marker {
  _circ.map = nil;
  [_mapView animateToLocation:marker.position];

  if ([marker.userData conformsToProtocol:@protocol(GMUCluster)]) {
    [_mapView animateToZoom:_mapView.camera.zoom +1];
    return YES;
  }

  _circ = [GMSCircle circleWithPosition:marker.position radius:800];
  _circ.fillColor = [UIColor colorWithRed: 0.67 green: 0.67 blue: 0.67 alpha: 0.5];
  _circ.map = _mapView;
  return NO;
}

10. Поздравления

Вы успешно создали свое первое приложение для iOS с использованием платформы Google Maps, включая загрузку Maps SDK для iOS, загрузку карты, работу с маркерами, управление и рисование на карте, а также добавление взаимодействия с пользователем.

Чтобы увидеть готовый код, проверьте готовый проект в каталоге /solution .

Что дальше?

В этой лабораторной работе мы рассмотрели лишь основы работы с Maps SDK для iOS. Теперь попробуйте добавить на карту некоторые из следующих функций:

  • Измените тип карты для отображения спутниковых, гибридных и рельефных карт.
  • Настройте другие взаимодействия с пользователем, такие как масштабирование и управление картой.
  • Добавьте информационные окна для отображения информации при нажатии на маркеры.
  • Ознакомьтесь с Places SDK для iOS , чтобы добавить в свое приложение расширенные функции и данные о местах платформы Google Карт.

Чтобы продолжить изучение дополнительных способов работы с платформой Google Карт в Интернете, ознакомьтесь со следующими ссылками: