Изменить интерфейс навигации

Используя Navigation SDK для iOS, вы можете изменить взаимодействие пользователя с вашей картой, определив, какие встроенные элементы управления и элементы пользовательского интерфейса отображаются на карте и какие жесты вы разрешаете. Вы также можете изменить внешний вид пользовательского интерфейса навигации. На странице «Политики» приведены рекомендации по допустимым изменениям пользовательского интерфейса навигации.

Элементы управления пользовательским интерфейсом карты

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

Компас

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

Если навигация включена и режим камеры установлен на «Следующий», компас остается видимым, а нажатие на компас переключает между наклонной и обзорной перспективами камеры.

По умолчанию компас отключен. Вы можете включить компас, установив для свойства compassButton GMSUISettings значение YES . Однако вы не можете заставить компас всегда отображаться.

Быстрый

mapView.settings.compassButton = true

Цель-C

mapView.settings.compassButton = YES;

Кнопка «Мое местоположение»

Кнопка «Мое местоположение» появляется в правом нижнем углу экрана только в том случае, если кнопка «Мое местоположение» включена. Когда пользователь нажимает кнопку, камера анимируется и фокусируется на текущем местоположении пользователя, если местоположение пользователя в данный момент известно. Вы можете включить эту кнопку, установив для свойства myLocationButton объекта GMSUISettings значение YES .

Быстрый

mapView.settings.myLocationButton = true

Цель-C

mapView.settings.myLocationButton = YES;

Кнопка повторного центрирования

Если навигация включена, кнопка повторного центрирования появляется, когда пользователь прокручивает вид карты, и исчезает, когда пользователь нажимает, чтобы перецентрировать карту. Чтобы разрешить появление кнопки recenter, установите для свойства recenterButtonEnabled GMSUISettings значение YES . Чтобы кнопка «recenter» не появлялась, установите для recenterButtonEnabled значение NO .

Быстрый

mapView.settings.isRecenterButtonEnabled = true

Цель-C

mapView.settings.recenterButtonEnabled = YES;

Аксессуары пользовательского интерфейса карты

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

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

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

  • navigationHeaderEnabled — контролирует, отображается ли заголовок навигации (по умолчанию — true ).
  • navigationFooterEnabled — управляет видимостью нижнего колонтитула навигации (по умолчанию — true ).
  • navigationHeaderPrimaryBackgroundColor — устанавливает основной цвет фона для заголовка навигации.
  • navigationHeaderSecondaryBackgroundColor — устанавливает дополнительный цвет фона для заголовка навигации.

В следующем примере кода показано включение видимости верхнего и нижнего колонтитула, затем установка navigationHeaderPrimaryBackgroundColor синего цвета, а для navigationHeaderSecondaryBackgroundColor — красного.

Быстрый

mapView.settings.isNavigationHeaderEnabled = true
mapView.settings.isNavigationFooterEnabled = true
mapView.settings.navigationHeaderPrimaryBackgroundColor = .blue
mapView.settings.navigationHeaderSecondaryBackgroundColor = .red

Цель-C

mapView.settings.navigationHeaderEnabled = YES;
mapView.settings.navigationFooterEnabled = YES;
mapView.settings.navigationHeaderPrimaryBackgroundColor = [UIColor blueColor];
mapView.settings.navigationHeaderSecondaryBackgroundColor = [UIColor redColor];

Вы можете настроить свое приложение, заменив дополнительный вид заголовка навигации собственным настраиваемым дополнительным представлением. Это можно сделать, создав представление, реализующее протокол GMSNavigationAccessoryView . Этот протокол имеет один обязательный метод: -heightForAccessoryViewConstrainedToSize:onMapView: . Вам предоставляется максимально доступный размер вашего представления в данном MapView, и вы должны указать высоту, необходимую для вашего представления.

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

Чтобы удалить представление настраиваемого аксессуара заголовка, передайте nil в setHeaderAccessoryView:

Если ваше представление должно изменить размер в любое время, вы можете вызвать invalidateLayoutForAccessoryView: , передав представление, размер которого необходимо изменить.

Пример

В следующем примере кода показано пользовательское представление, реализующее протокол GMSNavigationAccessoryView . Это настраиваемое представление затем используется для настройки настраиваемого представления аксессуаров заголовка навигации.

Быстрый

class MyCustomView: UIView, GMSNavigationAccessoryView {
…
  func heightForAccessoryViewConstrained(to size: CGSize, on mapView: GMSMapView) -> CGFloat {
    // viewHeight gets calculated as the height your view needs.
    return viewHeight
  }
…
}

let customView = MyCustomView(...)
mapView.setHeaderAccessory(customView)

// At some later point customView changes size.
mapView.invalidateLayout(forAccessoryView: customView)

// Remove the custom header accessory view.
mapView.setHeaderAccessory(nil)

Цель-C

@interface MyCustomView : UIView <GMSNavigationAccessoryView>
…
@end

@implementation MyCustomView
…
- (CGFloat)heightForAccessoryViewConstrainedToSize:(CGSize)size onMapView:(GMSMapView *)mapView {
  // viewHeight gets calculated as the height your view needs.
  return viewHeight;
}
…
@end

MyCustomView *customView = [[MyCustomView alloc] init…];
[_mapView setHeaderAccessoryView:customView];

// At some later point customView changes size.
[_mapView invalidateLayoutForAccessoryView:customView];

// Remove the custom header accessory view.
[_mapView setHeaderAccessoryView:nil];

Список направлений

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

  1. Включите кнопку точки входа после успешного завершения setDestinations на GMSNavigator (навигаторе) и активации guidanceActive на навигаторе.
  2. Когда пользователь нажимает кнопку точки входа, создайте GMSNavigationDirectionsListController (контроллер) с навигатором, связанным с GMSMapView ( mapView ).
  3. Добавьте контроллер в экземпляр UIViewController (контроллер представления) и добавьте directionsListView в качестве подпредставления контроллера представления. Методы reloadData invalidateLayout на контроллере следует вызывать так же, как и с UICollectionView .
  4. Поместите контроллер представления в иерархию контроллеров представления приложения.

В следующем примере кода показано добавление DirectionsListViewController .

Быстрый

override func viewDidLoad() {
  super.viewDidLoad()
  // Add the directionsListView to the host view controller's view.
  let directionsListView = directionsListController.directionsListView
  directionsListView.frame = self.view.frame
  self.view.addSubview(directionsListView)
  directionsListView.translatesAutoresizingMaskIntoConstraints = false
  directionsListView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
  directionsListView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
  directionsListView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
  directionsListView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
  ...
}

override func viewWillAppear(_ animated: Bool) {
  super.viewWillAppear(animated)
  // Ensure data is fresh when the view appears.
  directionsListController.reloadData()
  ...
}

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
  super.willTransition(to: newCollection, with: coordinator)
  // Invalidate the layout during rotation.
  coordinator.animate(alongsideTransition: {_ in
    self.directionsListController.invalidateLayout()
  })
  ...
}

Цель-C

- (void)viewDidLoad {
  [super viewDidLoad];
  // Add the directionsListView to the host view controller's view.
  UIView *directionsListView = _directionsListController.directionsListView;
  directionsListView.frame = self.view.bounds;
  [self.view addSubview:directionsListView];
  directionsListView.translatesAutoresizingMaskIntoConstraints = NO;
  [directionsListView.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES;
  [directionsListView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor].active = YES;
  [directionsListView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor].active = YES;
  [directionsListView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
  ...
}

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  // Ensure data is fresh when the view appears.
  [_directionsListController reloadData];
  ...
}

- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection
              withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
  [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];
  void(^animationBlock)(id <UIViewControllerTransitionCoordinatorContext>context) =
      ^void(id <UIViewControllerTransitionCoordinatorContext>context) {
    [_directionsListController invalidateLayout];
  };
  // Invalidate the layout during rotation.
  [coordinator animateAlongsideTransition:animationBlock
                               completion:nil];
  ...
}

...

Индикатор выполнения поездки

В навигацию добавлен индикатор выполнения поездки.

Индикатор выполнения поездки — это вертикальная полоса, которая появляется на правом конце карты при запуске навигации. Если эта функция включена, она отображает обзор всей поездки, а также пункт назначения и текущее положение водителя.

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

На индикаторе хода поездки отображаются следующие индикаторы состояния:

  • Статус трафика — статус предстоящего трафика.

  • Текущее местоположение — текущее местоположение водителя в поездке.

  • Пройденный маршрут — пройденный отрезок пути.

Включите индикатор выполнения поездки, установив свойство navigationTripProgressBarEnabled в GMSUISettings .

Быстрый

mapView.settings.isNavigationTripProgressBarEnabled = true

Цель-C

mapView.settings.navigationTripProgressBarEnabled = YES;

Светофоры и знаки остановки

Знаки остановки и светофоры, отображаемые во время навигации.

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

По умолчанию светофоры и знаки остановки отключены в Navigation SDK для iOS. Чтобы включить эту функцию, вызовите настройки GMSMapView для каждой опции независимо: showsTrafficLights и showsStopSigns .


Быстрый

mapView.settings.showsTrafficLights = YES;
mapView.settings.showsStopSigns = YES;

Цель-C

mapView.settings.showsTrafficLights = true;
mapView.settings.showsStopSigns = true;

Контроль спидометра

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

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

Чтобы отобразить элемент управления ограничением скорости, установите для свойства shouldDisplaySpeedometer GMSUISettings значение YES . Чтобы отключить отображение контроля ограничения скорости, установите для shouldDisplaySpeedometer значение NO .

Быстрый

mapView.shouldDisplaySpeedometer = true

Цель-C

mapView.shouldDisplaySpeedometer = YES;

Дополнительную информацию о настройке оповещений для спидометра см. в разделе Настройка оповещений спидометра .

Маркеры назначения

Вы можете показать или скрыть маркеры назначения для данного маршрута, установив свойство showsDestinationMarkers в GMSUISettings . В следующем примере показано отключение маркеров назначения.

Быстрый

mapView.settings.showsDestinationMarkers = false

Цель-C

mapView.settings.showsDestinationMarkers = NO;

Возможности карты

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

Отключить жесты карты по умолчанию

Вы можете отключить жесты по умолчанию на карте, задав свойства класса GMSUISettings , который доступен как свойство GMSMapView . Следующие жесты можно включить и отключить программно. Обратите внимание, что отключение жеста не ограничит программный доступ к настройкам камеры.

  • scrollGestures — контролирует, включены или отключены жесты прокрутки. Если эта функция включена, пользователи могут проводить пальцем по экрану, чтобы панорамировать камеру.
  • zoomGestures — контролирует, включены или отключены жесты масштабирования. Если эта функция включена, пользователи могут дважды коснуться, коснуться двумя пальцами или свести пальцы, чтобы увеличить масштаб камеры. Обратите внимание, что двойное нажатие или сжатие при включении scrollGestures может привести к панорамированию камеры в указанную точку.
  • tiltGestures — контролирует, включены или отключены жесты наклона. Если эта функция включена, пользователи могут провести двумя пальцами вертикально вниз или вверх, чтобы наклонить камеру.
  • rotateGestures — контролирует, включены или отключены жесты поворота. Если эта функция включена, пользователи могут использовать жест поворота двумя пальцами для поворота камеры.

В этом примере жесты панорамирования и масштабирования отключены.

Быстрый

mapView.settings.scrollGestures = false
mapView.settings.zoomGestures = false

Цель-C

mapView.settings.scrollGestures = NO;
mapView.settings.zoomGestures = NO;

Элементы управления положением и элементы пользовательского интерфейса

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

  • navigationHeaderLayoutGuide
  • navigationFooterLayoutGuide

В следующем примере кода показано использование направляющих макета для размещения пары меток в представлении карты:

Быстрый

/* Add a label to the top left, positioned below the header. */
let topLabel = UILabel()
topLabel.text = "Top Left"
mapView.addSubview(topLabel)
topLabel.translatesAutoresizingMaskIntoConstraints = false
topLabel.topAnchor.constraint(equalTo: mapView.navigationHeaderLayoutGuide.bottomAnchor).isActive = true
topLabel.leadingAnchor.constraint(equalTo: mapView.leadingAnchor).isActive = true

/* Add a label to the bottom right, positioned above the footer. */
let bottomLabel = UILabel()
bottomLabel.text = "Bottom Right"
mapView.addSubview(bottomLabel)
bottomLabel.translatesAutoresizingMaskIntoConstraints = false
bottomLabel.bottomAnchor.constraint(equalTo: mapView.navigationFooterLayoutGuide.topAnchor).isActive = true
bottomLabel.trailingAnchor.constraint(equalTo: mapView.trailingAnchor).isActive = true

Цель-C

/* Add a label to the top left, positioned below the header. */
UILabel *topLabel = [[UILabel alloc] init];
topLabel.text = @"Top Left";
[view addSubview:topLabel];
topLabel.translatesAutoresizingMaskIntoConstraints = NO;
[topLabel.topAnchor
    constraintEqualToAnchor:mapView.navigationHeaderLayoutGuide.bottomAnchor].active = YES;
[topLabel.leadingAnchor constraintEqualToAnchor:mapView.leadingAnchor].active = YES;

/* Add a label to the bottom right, positioned above the footer. */
UILabel *bottomLabel = [[UILabel alloc] init];
bottomLabel.text = @"Bottom Right";
[view addSubview:bottomLabel];
bottomLabel.translatesAutoresizingMaskIntoConstraints = NO;
[bottomLabel.bottomAnchor
    constraintEqualToAnchor:mapView.navigationFooterLayoutGuide.topAnchor].active = YES;
[bottomLabel.trailingAnchor constraintEqualToAnchor:mapView.trailingAnchor].active = YES;

Скрыть альтернативные маршруты

Когда пользовательский интерфейс перегружен слишком большим количеством информации, вы можете уменьшить беспорядок, отображая меньше альтернативных маршрутов, чем по умолчанию (два), или вообще не отображая альтернативные маршруты. Вы можете настроить этот параметр перед получением маршрутов, настроив GMSNavigationRoutingOptions и задав для параметра alternateRoutesStrategy одно из следующих значений перечисления:

Значение перечисления Описание
GMSNavigationАльтернативныеМаршрутыСтратегияВсе По умолчанию. Отображает до двух альтернативных маршрутов.
GMSNavigationАльтернативныеМаршрутыСтратегияOne Отображает один альтернативный маршрут (если он доступен).
GMSNavigationАльтернативныеМаршрутыСтратегияНет Скрывает альтернативные маршруты.

Пример

В следующем примере кода показано, как полностью скрыть альтернативные маршруты.

Быстрый

let routingOptions = GMSNavigationRoutingOptions(alternateRoutesStrategy: .none)
navigator?.setDestinations(destinations,
                           routingOptions: routingOptions) { routeStatus in
  ...
}

Цель-C

GMSNavigationRoutingOptions *routingOptions = [[GMSNavigationRoutingOptions alloc] initWithAlternateRoutesStrategy:GMSNavigationAlternateRoutesStrategyNone];
[navigator setDestinations:destinations
            routingOptions:routingOptions
                  callback:^(GMSRouteStatus routeStatus){...}];