Modifier l'interface utilisateur de navigation

Le SDK Navigation pour iOS vous permet de modifier l'expérience utilisateur avec votre carte en déterminant quels éléments et commandes d'interface utilisateur intégrés apparaissent sur la carte, ainsi que les gestes que vous autorisez. Vous pouvez également modifier l'apparence visuelle de l'UI de navigation. Consultez la page des règles pour connaître les modifications acceptables apportées à l'interface utilisateur de navigation.

Commandes de l'interface utilisateur de la carte

Le SDK Navigation fournit des commandes d'interface utilisateur intégrées semblables à celles que l'on trouve dans l'application Google Maps pour iOS. Vous pouvez activer et désactiver la visibilité de ces commandes à l'aide de la classe GMSUISettings. Les modifications apportées à cette classe se reflètent immédiatement sur la carte.

Boussole

Le SDK Navigation fournit une image de boussole qui apparaît dans l'angle supérieur droit de la carte, dans certaines conditions et uniquement lorsqu'elle est activée. La boussole n'apparaît que lorsque la caméra est orientée de sorte que sa direction ou son inclinaison sont différentes de zéro. Lorsque l'utilisateur clique sur la boussole, la caméra s'anime pour revenir à une position avec un azimut de zéro (orientation par défaut) et la boussole disparaît progressivement juste après.

Si la navigation est activée et que le mode d'appareil photo est défini sur "suivi", la boussole reste visible. Appuyer sur la boussole permet de basculer entre les perspectives d'appareil photo inclinée et d'aperçu.

La boussole est désactivée par défaut. Vous pouvez activer la boussole en définissant la propriété compassButton de GMSUISettings sur true. En revanche, vous ne pouvez pas forcer l'affichage permanent de la boussole.

Swift

mapView.settings.compassButton = true

Objective-C

mapView.settings.compassButton = YES;

Bouton "Ma position"

Le bouton "Ma position" apparaît en bas à droite de l'écran uniquement lorsque le bouton correspondant est activé. Lorsqu'un utilisateur clique sur ce bouton, la caméra s'anime pour se concentrer sur sa position actuelle, si celle-ci est actuellement connue. Vous pouvez activer le bouton en définissant la propriété myLocationButton de GMSUISettings sur true.

Swift

mapView.settings.myLocationButton = true

Objective-C

mapView.settings.myLocationButton = YES;

Bouton "Recentrer"

Lorsque la navigation est activée, le bouton de recentrage s'affiche lorsque l'utilisateur fait défiler la vue de la carte et disparaît lorsque l'utilisateur appuie pour recentrer la carte. Pour permettre l'affichage du bouton de recentrage, définissez la propriété recenterButtonEnabled de GMSUISettings sur true. Pour empêcher l'affichage du bouton de recentrage, définissez recenterButtonEnabled sur false.

Swift

mapView.settings.isRecenterButtonEnabled = true

Objective-C

mapView.settings.recenterButtonEnabled = YES;

Accessoires de l'UI de la carte

Le SDK Navigation fournit des accessoires d'interface utilisateur qui s'affichent pendant la navigation, semblables à ceux que l'on trouve dans l'application Google Maps pour iOS. Vous pouvez ajuster la visibilité ou l'apparence visuelle de ces commandes comme décrit dans cette section. Les modifications que vous apportez ici s'appliquent lors du prochain trajet de l'utilisateur.

Lors de la navigation, l'en-tête de navigation s'affiche en haut de l'écran et le pied de page de navigation en bas. L'en-tête de navigation indique le nom de la rue et l'orientation du prochain virage sur l'itinéraire, ainsi que l'orientation du virage suivant. Le pied de page de navigation affiche le temps et la distance estimés jusqu'à la destination, ainsi que l'heure d'arrivée estimée.

Vous pouvez activer ou désactiver la visibilité de l'en-tête et du pied de page de navigation, et définir leurs couleurs de manière programmatique à l'aide des propriétés suivantes:

  • navigationHeaderEnabled : indique si l'en-tête de navigation est visible (la valeur par défaut est true).
  • navigationFooterEnabled : indique si le pied de page de navigation est visible (true par défaut).
  • navigationHeaderPrimaryBackgroundColor : définit la couleur d'arrière-plan principale de l'en-tête de navigation.
  • navigationHeaderSecondaryBackgroundColor : définit la couleur d'arrière-plan secondaire de l'en-tête de navigation.

L'exemple de code suivant montre comment activer la visibilité de l'en-tête et du pied de page, puis définir navigationHeaderPrimaryBackgroundColor sur bleu et navigationHeaderSecondaryBackgroundColor sur rouge.

Swift

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

Objective-C

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

Vous pouvez personnaliser votre application en remplaçant la vue de l'en-tête de navigation secondaire par votre propre vue d'accessoire personnalisée. Pour ce faire, créez une vue qui implémente le protocole GMSNavigationAccessoryView. Ce protocole comporte une méthode obligatoire: -heightForAccessoryViewConstrainedToSize:onMapView:. Vous disposez de la taille maximale disponible pour votre vue sur la mapView donnée, et vous devez fournir la hauteur requise pour votre vue.

Vous pouvez ensuite transmettre cette vue à la mapView en appelant setHeaderAccessoryView:. La mapView anime les vues actuelles, puis anime votre vue personnalisée. L'en-tête de navigation doit être visible pour que votre vue personnalisée s'affiche.

Pour supprimer la vue d'accessoire d'en-tête personnalisé, transmettez nil à setHeaderAccessoryView:.

Si votre vue doit changer de taille à tout moment, vous pouvez appeler invalidateLayoutForAccessoryView: en transmettant la vue qui doit changer de taille.

Exemple

L'exemple de code suivant illustre une vue personnalisée qui implémente le protocole GMSNavigationAccessoryView. Cette vue personnalisée est ensuite utilisée pour définir une vue accessoire d'en-tête de navigation personnalisée.

Swift

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)

Objective-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];

Liste des itinéraires

Vous pouvez fournir des instructions détaillées dans votre application. L'exemple suivant montre une façon de procéder. Ces étapes peuvent varier en fonction de votre implémentation.

  1. Activez un bouton de point d'entrée une fois que setDestinations sur le GMSNavigator (navigateur) a bien été exécuté et que guidanceActive sur le navigateur a été activé.
  2. Lorsqu'un utilisateur appuie sur le bouton du point d'entrée, créez un GMSNavigationDirectionsListController (contrôleur) avec le navigateur associé au GMSMapView (mapView).
  3. Ajoutez le contrôleur à une instance de UIViewController (contrôleur de vue) et ajoutez directionsListView en tant que sous-vue du contrôleur de vue. Les méthodes reloadData et invalidateLayout du contrôleur doivent être appelées comme pour un UICollectionView.
  4. Transférez le contrôleur de vue dans la hiérarchie du contrôleur de vue de l'application.

L'exemple de code suivant montre comment ajouter un DirectionsListViewController.

Swift

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()
  })
  ...
}

Objective-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];
  ...
}

...

Barre de progression du trajet

Barre de progression du trajet ajoutée à la navigation.

La barre de progression du trajet est une barre verticale qui s'affiche sur le bord droit de la carte lorsque la navigation commence. Lorsqu'elle est activée, elle affiche un aperçu de l'ensemble du trajet, ainsi que la destination et la position actuelle de l'utilisateur.

Cela permet aux utilisateurs d'anticiper rapidement les problèmes à venir, tels que le trafic, sans avoir à faire un zoom avant. Il peut ensuite modifier l'itinéraire si nécessaire. Si l'utilisateur modifie l'itinéraire, la barre de progression se réinitialise comme si un nouveau trajet avait commencé à partir de ce point.

La barre de progression du trajet affiche les indicateurs d'état suivants:

  • État du trafic : état du trafic à venir.

  • Position actuelle : position actuelle du conducteur sur le trajet.

  • Durée du trajet : durée du trajet.

Activez la barre de progression du trajet en définissant la propriété navigationTripProgressBarEnabled dans GMSUISettings.

Swift

mapView.settings.isNavigationTripProgressBarEnabled = true

Objective-C

mapView.settings.navigationTripProgressBarEnabled = YES;

Feux de circulation et panneaux Stop

Panneaux Stop et feux de signalisation affichés pendant la navigation

Vous pouvez activer les feux de signalisation et les panneaux Stop dans mapView. Grâce à cette fonctionnalité, l'utilisateur peut activer l'affichage d'icônes de feux de circulation ou de panneaux d'arrêt le long de son itinéraire, ce qui fournit un meilleur contexte pour des trajets plus efficaces et plus précis.

Par défaut, les feux de circulation et les panneaux d'arrêt sont désactivés dans le SDK Navigation pour iOS. Pour activer cette fonctionnalité, appelez les paramètres GMSMapView pour chaque option indépendamment : showsTrafficLights et showsStopSigns.


Swift

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

Objective-C

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

Commande du compteur de vitesse

Lorsque la navigation est activée et que le mode de déplacement est défini sur "En voiture", le SDK Navigation pour iOS affiche un contrôle de la limite de vitesse dans le coin inférieur de la carte, qui indique la limite de vitesse actuelle. Lorsque le conducteur dépasse la limite de vitesse, le contrôle se développe pour afficher un deuxième compteur de vitesse avec la vitesse actuelle du conducteur.

Vous pouvez définir des niveaux d'alerte pour modifier la mise en forme de l'affichage du compteur de vitesse lorsque le conducteur dépasse la limite de vitesse d'un montant spécifié. Par exemple, vous pouvez spécifier que la vitesse actuelle s'affiche avec une couleur de texte rouge lorsque le conducteur dépasse la limite de vitesse de 8 km/h et avec une couleur d'arrière-plan rouge lorsque le conducteur dépasse la limite de vitesse de 16 km/h.

Pour afficher la commande de limitation de vitesse, définissez la propriété shouldDisplaySpeedometer de GMSUISettings sur true. Pour désactiver l'affichage de la commande de limite de vitesse, définissez shouldDisplaySpeedometer sur false.

Swift

mapView.shouldDisplaySpeedometer = true

Objective-C

mapView.shouldDisplaySpeedometer = YES;

Pour en savoir plus sur la configuration d'alertes pour le compteur de vitesse, consultez la section Configurer des alertes pour le compteur de vitesse.

Repères de destination

Vous pouvez afficher ou masquer les repères de destination d'un itinéraire donné en définissant la propriété showsDestinationMarkers de GMSUISettings. L'exemple suivant montre comment désactiver les repères de destination.

Swift

mapView.settings.showsDestinationMarkers = false

Objective-C

mapView.settings.showsDestinationMarkers = NO;

Fonctionnalités de l'expérience cartographique

Le SDK Navigation vous permet de personnaliser davantage l'expérience de navigation pour vos utilisateurs. Les modifications que vous apportez à votre instance sont répercutées lors de la prochaine mise à jour de votre application par l'utilisateur.

Désactiver les gestes de carte par défaut

Vous pouvez désactiver les gestes par défaut sur la carte en définissant les propriétés de la classe GMSUISettings, qui est disponible en tant que propriété de GMSMapView. Les gestes suivants peuvent être activés et désactivés par programmation. Notez que la désactivation du geste ne limite pas l'accès programmatique aux paramètres de l'appareil photo.

  • scrollGestures : permet de déterminer si les gestes de défilement sont activés ou désactivés. Si ces gestes sont activés, les utilisateurs peuvent balayer l'écran afin d'effectuer un panorama avec l'appareil photo.
  • zoomGestures : détermine si les gestes de zoom sont activés ou désactivés. Si cette option est activée, les utilisateurs peuvent appuyer deux fois, appuyer avec deux doigts ou pincer pour faire un zoom sur la caméra. Notez que le double appui ou le pincement lorsque scrollGestures est activé peut faire pivoter la caméra vers le point spécifié.
  • tiltGestures : permet de contrôler si les gestes d'inclinaison sont activés ou désactivés. Si cette option est activée, les utilisateurs peuvent balayer l'écran vers le bas ou vers le haut avec deux doigts pour incliner la caméra.
  • rotateGestures : indique si les gestes de rotation sont activés ou désactivés. Si cette option est activée, les utilisateurs peuvent faire pivoter la caméra en effectuant un geste de rotation à deux doigts.

Dans cet exemple, les gestes de panoramique et de zoom ont été désactivés.

Swift

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

Objective-C

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

Positionner les commandes et les éléments d'interface utilisateur

Vous pouvez positionner les commandes et d'autres éléments d'interface utilisateur par rapport à la position de l'en-tête et du pied de page de navigation à l'aide des propriétés suivantes:

  • navigationHeaderLayoutGuide
  • navigationFooterLayoutGuide

L'exemple de code suivant montre comment utiliser les guides de mise en page pour positionner une paire d'étiquettes dans la vue Carte:

Swift

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

Objective-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;

Masquer les itinéraires bis

Lorsque l'interface utilisateur est trop chargée d'informations, vous pouvez réduire l'encombrement en affichant moins de routes de substitution que la valeur par défaut (deux) ou en n'affichant aucune route de substitution. Vous pouvez configurer cette option avant d'extraire les itinéraires en configurant GMSNavigationRoutingOptions et en définissant alternateRoutesStrategy sur l'une des valeurs d'énumération suivantes:

Valeur d'énumérationDescription
GMSNavigationAlternateRoutesStrategyAll Par défaut. Affiche jusqu'à deux itinéraires bis.
GMSNavigationAlternateRoutesStrategyOne Affiche un autre itinéraire (s'il y en a un).
GMSNavigationAlternateRoutesStrategyNone Masque les itinéraires bis.

Exemple

L'exemple de code suivant montre comment masquer complètement les itinéraires bis.

Swift

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

Objective-C

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