Modificare l'interfaccia utente di navigazione

Con l'SDK di navigazione per iOS, puoi modificare l'esperienza utente con la mappa stabilendo quali elementi e controlli dell'interfaccia utente integrati vengono visualizzati sulla mappa e quali gesti consentire. Puoi anche modificare l'aspetto visivo della UI di navigazione. Per linee guida sulle modifiche accettabili all'interfaccia utente di navigazione, consulta la pagina Norme.

Controlli UI mappa

L'SDK di navigazione fornisce alcuni controlli integrati dell'interfaccia utente simili a quelli disponibili nell'applicazione Google Maps per iOS. Puoi attivare/disattivare la visibilità di questi controlli utilizzando la classe GMSUISettings. Le modifiche che apporti in questo corso si riflettono immediatamente sulla mappa.

Bussola

L'SDK di navigazione fornisce un'immagine bussola che viene visualizzata nell'angolo in alto a destra della mappa in determinate circostanze e solo quando è attivato. La bussola appare solo quando la fotocamera è orientata in modo tale da avere un orientamento diverso dal nord esatto (un orientamento diverso da zero). Quando l'utente fa clic sulla bussola, la fotocamera ritorna in una posizione con un rilevamento zero (orientamento predefinito) e la bussola svanisce poco dopo.

Se la navigazione è attiva e la modalità fotocamera è impostata su "Segui", la bussola rimane visibile e se tocchi la bussola puoi passare dalla prospettiva inclinata a quella panoramica e viceversa.

La bussola è disattivata per impostazione predefinita. Per attivare la bussola, imposta la proprietà compassButton di GMSUISettings su true. Tuttavia, non puoi forzare la visualizzazione della bussola.

Swift

mapView.settings.compassButton = true

Objective-C

mapView.settings.compassButton = YES;

Pulsante La mia posizione

Il pulsante La mia posizione viene visualizzato nell'angolo in basso a destra dello schermo solo quando è attivato. Quando un utente fa clic sul pulsante, la videocamera si anima per mettere a fuoco la posizione corrente dell'utente, se questa è attualmente nota. Per attivare il pulsante, imposta la proprietà myLocationButton di GMSUISettings su true.

Swift

mapView.settings.myLocationButton = true

Objective-C

mapView.settings.myLocationButton = YES;

Pulsante Ricentra

Quando la navigazione è abilitata, il pulsante Ricentra appare quando l'utente scorre la visualizzazione mappa e scompare quando l'utente tocca per centrare nuovamente la mappa. Per consentire la visualizzazione del pulsante di ricentramento, imposta la proprietà recenterButtonEnabled di GMSUISettings su true. Per evitare che il pulsante di ricentramento venga visualizzato, imposta recenterButtonEnabled su false.

Swift

mapView.settings.isRecenterButtonEnabled = true

Objective-C

mapView.settings.recenterButtonEnabled = YES;

Accessori UI mappa

L'SDK di navigazione fornisce accessori per l'interfaccia utente visualizzati durante la navigazione simili a quelli presenti nell'applicazione Google Maps per iOS. Puoi modificare la visibilità o l'aspetto visivo di questi controlli come descritto in questa sezione. Le modifiche che apporti qui si riflettono nel prossimo viaggio dell'utente.

Durante la navigazione, l'intestazione della navigazione viene visualizzata nella parte superiore dello schermo e il piè di pagina di navigazione viene visualizzato in basso. L'intestazione della navigazione mostra il nome della via e la direzione per la prossima svolta del percorso, nonché la direzione della svolta successiva. Il piè di pagina di navigazione mostra l'orario e la distanza stimati per raggiungere la destinazione, nonché l'orario di arrivo previsto.

Puoi attivare/disattivare la visibilità dell'intestazione e del piè di pagina di navigazione e impostare i colori in modo programmatico utilizzando le seguenti proprietà:

  • navigationHeaderEnabled: controlla se l'intestazione di navigazione è visibile (il valore predefinito è true).
  • navigationFooterEnabled: controlla se il piè di pagina di navigazione è visibile (il valore predefinito è true).
  • navigationHeaderPrimaryBackgroundColor: imposta il colore di sfondo principale per l'intestazione di navigazione.
  • navigationHeaderSecondaryBackgroundColor: imposta il colore di sfondo secondario per l'intestazione della navigazione.

Il seguente esempio di codice mostra l'attivazione della visibilità per l'intestazione e il piè di pagina, quindi l'impostazione di navigationHeaderPrimaryBackgroundColor su blu e di navigationHeaderSecondaryBackgroundColor su rosso.

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

Puoi personalizzare l'app sostituendo la visualizzazione dell'intestazione di navigazione secondaria con la tua visualizzazione degli accessori personalizzata. Puoi farlo creando una vista che implementa il protocollo GMSNavigationAccessoryView. Questo protocollo ha un metodo obbligatorio: -heightForAccessoryViewConstrainedToSize:onMapView:. Vengono stabilite le dimensioni massime disponibili per la visualizzazione nella visualizzazione MapView specificata e l'altezza richiesta dalla visualizzazione.

Puoi quindi passare questa visualizzazione a mapView chiamando setHeaderAccessoryView: La mappa mapView anima tutte le visualizzazioni correnti e poi anima nella tua visualizzazione personalizzata. L'intestazione della navigazione deve essere visibile per poter mostrare la visualizzazione personalizzata.

Per rimuovere la visualizzazione personalizzata degli accessori dell'intestazione, passa nil a setHeaderAccessoryView:.

Se la visualizzazione deve cambiare dimensione in qualsiasi momento, puoi chiamare invalidateLayoutForAccessoryView:, passando la vista che deve cambiare le dimensioni.

Esempio

Il seguente esempio di codice mostra una visualizzazione personalizzata che implementa il protocollo GMSNavigationAccessoryView. Questa visualizzazione personalizzata viene poi utilizzata per impostare una vista accessoria per l'intestazione di navigazione personalizzata.

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

Elenco indicazioni stradali

Puoi fornire indicazioni stradali dettagliate nella tua app. L'esempio seguente mostra un possibile modo per farlo. Questi passaggi possono variare a seconda della tua implementazione.

  1. Abilita un pulsante del punto di ingresso dopo che setDestinations su GMSNavigator (navigatore) è stato completato correttamente e guidanceActive sul navigatore è stato attivato.
  2. Quando un utente tocca il pulsante del punto di ingresso, crea un GMSNavigationDirectionsListController (controller) con il navigatore associato a GMSMapView (mapView).
  3. Aggiungi il controller a un'istanza di UIViewController (view controller) e aggiungi directionsListView come vista secondaria del controller di visualizzazione. I metodi reloadData e invalidateLayout sul controller devono essere chiamati come faresti con un UICollectionView.
  4. Trasferisci il controller di visualizzazione alla gerarchia di controller di visualizzazione dell'app.

L'esempio di codice seguente mostra l'aggiunta di 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];
  ...
}

...

Barra di avanzamento del percorso

La barra di avanzamento del percorso aggiunta alla navigazione.

La barra di avanzamento del percorso è una barra verticale che viene visualizzata sul bordo destro finale della mappa quando inizia la navigazione. Se attivata, visualizza una panoramica di un intero viaggio, insieme alla destinazione e alla posizione attuale dell'utente.

Consente agli utenti di prevedere rapidamente eventuali problemi imminenti, come il traffico, senza dover aumentare lo zoom. Possono quindi modificare il percorso, se necessario. Se l'utente reindirizza la corsa, la barra di avanzamento si reimposta come se da quel punto fosse iniziato una nuova corsa.

La barra di avanzamento del percorso mostra i seguenti indicatori di stato:

  • Stato del traffico: lo stato del traffico imminente.

  • Posizione attuale: la posizione attuale del conducente nel percorso.

  • Percorso trascorso: la parte trascorsa del percorso.

Attiva la barra di avanzamento della corsa impostando la proprietà navigationTripProgressBarEnabled in GMSUISettings.

Swift

mapView.settings.isNavigationTripProgressBarEnabled = true

Objective-C

mapView.settings.navigationTripProgressBarEnabled = YES;

Semafori e segnali di stop

Segnali di stop e semafori mostrati durante la navigazione.

Puoi attivare i semafori e i segnali di stop nel mapView. Con questa funzionalità, l'utente può attivare la visualizzazione dei semafori o delle icone dei segnali di stop lungo il percorso, fornendo un contesto migliore per corse più efficienti e accurate.

Per impostazione predefinita, i semafori e i segnali di stop sono disattivati nell'SDK di navigazione per iOS. Per attivare questa funzionalità, richiama le impostazioni di GMSMapView per ogni opzione in modo indipendente: showsTrafficLights e showsStopSigns.


Swift

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

Objective-C

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

Controllo del tachimetro

Quando la navigazione è attivata e la modalità di viaggio è impostata su Auto, l'SDK di navigazione per iOS mostra un controllo del limite di velocità nell'angolo inferiore della mappa che mostra il limite di velocità corrente. Quando il conducente supera il limite di velocità, il controllo si espande e viene visualizzato un secondo tachimetro con la velocità attuale del conducente.

Puoi impostare livelli di avviso per modificare la formattazione del display del tachimetro quando il conducente supera il limite di velocità di un determinato valore. Ad esempio, puoi specificare che la velocità corrente venga visualizzata con un testo di colore rosso quando il conducente supera il limite di velocità di 8 km/h e con un colore di sfondo rosso quando il conducente supera il limite di velocità di 16 km/h.

Per visualizzare il controllo del limite di velocità, imposta la proprietà shouldDisplaySpeedometer di GMSUISettings su true. Per disattivare la visualizzazione del controllo del limite di velocità, imposta shouldDisplaySpeedometer su false.

Swift

mapView.shouldDisplaySpeedometer = true

Objective-C

mapView.shouldDisplaySpeedometer = YES;

Per ulteriori informazioni sull'impostazione degli avvisi per il tachimetro, consulta Configurare gli avvisi sul tachimetro.

Indicatori di destinazione

Puoi mostrare o nascondere gli indicatori di destinazione per un determinato percorso impostando la proprietà showsDestinationMarkers di GMSUISettings. L'esempio seguente mostra la disattivazione degli indicatori di destinazione.

Swift

mapView.settings.showsDestinationMarkers = false

Objective-C

mapView.settings.showsDestinationMarkers = NO;

Funzionalità relative all'esperienza sulla mappa

L'SDK di navigazione consente di apportare ulteriori personalizzazioni all'esperienza di navigazione degli utenti. Le modifiche apportate all'istanza vengono applicate durante il successivo aggiornamento dell'app da parte dell'utente.

Disattiva gesti mappa predefiniti

Puoi disattivare i gesti predefiniti sulla mappa impostando le proprietà della classe GMSUISettings, disponibile come proprietà di GMSMapView. I seguenti gesti possono essere attivati e disattivati in modo programmatico. Tieni presente che la disattivazione del gesto non limiterà l'accesso programmatico alle impostazioni della fotocamera.

  • scrollGestures: consente di stabilire se attivare o disattivare i gesti di scorrimento. Se questa impostazione è attiva, gli utenti possono scorrere per eseguire la panoramica della fotocamera.
  • zoomGestures: consente di stabilire se attivare o disattivare i gesti di zoom. Se questa opzione è attiva, gli utenti possono toccare due volte, toccare con due dita o pizzicare per eseguire lo zoom della fotocamera. Tieni presente che toccare due volte o pizzicare quando scrollGestures è attivo può eseguire una panoramica della fotocamera nel punto specificato.
  • tiltGestures: consente di attivare o disattivare i gesti di inclinazione. Se questa impostazione è attiva, gli utenti possono scorrere verso il basso o verso l'alto con due dita per inclinare la fotocamera.
  • rotateGestures: consente di stabilire se attivare o disattivare i gesti di rotazione. Se questa opzione è attiva, gli utenti possono usare un gesto di rotazione con due dita per ruotare la fotocamera.

In questo esempio, sono stati disattivati entrambi i gesti di panoramica e zoom.

Swift

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

Objective-C

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

Controlli di posizione ed elementi UI

Puoi posizionare i controlli e altri elementi dell'interfaccia utente in base alla posizione dell'intestazione e del piè di pagina di navigazione utilizzando le seguenti proprietà:

  • navigationHeaderLayoutGuide
  • navigationFooterLayoutGuide

Il seguente esempio di codice mostra l'utilizzo delle guide al layout per posizionare una coppia di etichette nella visualizzazione mappa:

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;

Nascondi percorsi alternativi

Quando l'interfaccia utente è piena di informazioni, puoi ridurre il disordine visualizzando un numero minore di percorsi alternativi rispetto a quello predefinito (due) o eliminando del tutto i percorsi alternativi. Puoi configurare questa opzione prima di recuperare le route configurando GMSNavigationRoutingOptions e impostando alternateRoutesStrategy con uno dei seguenti valori di enumerazione:

Valore di enumerazioneDescrizione
GMSNavigazioneAlternativePercorsiStrategia Predefinita. Mostra fino a due percorsi alternativi.
GMSNavigazioneAlternativePercorsiStrategiaUno Visualizza un percorso alternativo (se disponibile).
GMSNavigationAlternateRoutesStrategyNone Nasconde i percorsi alternativi.

Esempio

Il seguente esempio di codice mostra come nascondere completamente i percorsi alternativi.

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