Modificare l'interfaccia utente di navigazione

Con Navigation SDK per iOS, puoi modificare l'esperienza utente con la tua mappa determinando quali elementi e controlli dell'interfaccia utente integrati devono essere visualizzati sulla mappa e quali gesti consentire. Puoi anche modificare l'aspetto visivo dell'interfaccia utente di Navigazione. Consulta la pagina Norme per le linee guida sulle modifiche accettabili all'interfaccia utente di navigazione.

Controlli dell'interfaccia utente della mappa

L'SDK Navigation fornisce alcuni controlli UI integrati simili a quelli presenti nell'applicazione Google Maps per iOS. Puoi attivare/disattivare la visibilità di questi controlli utilizzando la classe GMSUISettings. Le modifiche apportate a questa classe vengono applicate immediatamente alla mappa.

Bussola

L'SDK Navigation fornisce un'immagine della bussola che viene visualizzata nell'angolo in alto a destra della mappa in determinate circostanze e solo se attivata. La bussola viene visualizzata solo quando la videocamera è orientata in modo da avere un orientamento diverso dal nord esatto (un orientamento diverso da zero). Quando l'utente fa clic sulla bussola, la videocamera torna in animazione in una posizione con un rilevamento pari a zero (l'orientamento predefinito) e la bussola scompare poco dopo.

Se la navigazione è attivata e la modalità fotocamera è impostata su "Inseguimento", la bussola rimane visibile e toccandola puoi passare dalla visuale inclinata a quella panoramica e viceversa.

La bussola è disattivata per impostazione predefinita. Puoi attivare la bussola impostando 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 se è attivato. Quando un utente fa clic sul pulsante, la fotocamera si anima per mettere a fuoco la posizione attuale dell'utente, se è attualmente nota. Puoi attivare il pulsante impostando la proprietà myLocationButton di GMSUISettings su true.

Swift

mapView.settings.myLocationButton = true

Objective-C

mapView.settings.myLocationButton = YES;

Pulsante Ricentra

Quando la navigazione è attiva, il pulsante di recentrazione viene visualizzato quando l'utente scorri la visualizzazione della mappa e scompare quando l'utente tocca per recentrare la mappa. Per consentire la visualizzazione del pulsante di recentrazione, imposta la proprietà recenterButtonEnabled di GMSUISettings su true. Per impedire la visualizzazione del pulsante di recente, imposta recenterButtonEnabled su false.

Swift

mapView.settings.isRecenterButtonEnabled = true

Objective-C

mapView.settings.recenterButtonEnabled = YES;

Accessori dell'interfaccia utente della mappa

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

Durante la navigazione, l'intestazione di navigazione viene visualizzata nella parte superiore dello schermo e il piè di pagina di navigazione nella parte inferiore. L'intestazione di navigazione mostra il nome della strada e la direzione della svolta successiva sul percorso, nonché la direzione della svolta successiva. Il piè di pagina della navigazione mostra il tempo stimato e la distanza dalla destinazione, nonché l'ora di arrivo stimata.

Puoi attivare/disattivare la visibilità del riquadro di navigazione e impostarne 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 della navigazione è visibile (il valore predefinito è true).
  • navigationHeaderPrimaryBackgroundColor: imposta il colore di sfondo primario per l'intestazione di navigazione.
  • navigationHeaderSecondaryBackgroundColor: imposta il colore di sfondo secondario per l'intestazione di navigazione.

Il seguente esempio di codice mostra come attivare la visibilità per l'intestazione e il piè di pagina, quindi imposta navigationHeaderPrimaryBackgroundColor su blu e 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 la tua app sostituendo la visualizzazione dell'intestazione di navigazione secondaria con la tua visualizzazione dell'accessorio personalizzata. Per farlo, devi creare una vista che implementi il protocollo GMSNavigationAccessoryView. Questo protocollo ha un metodo obbligatorio: -heightForAccessoryViewConstrainedToSize:onMapView:. Ti viene comunicata la dimensione massima disponibile per la visualizzazione nella mappa indicata e devi fornire l'altezza richiesta dalla visualizzazione.

Puoi quindi passare questa visualizzazione a mapView chiamando setHeaderAccessoryView:. La visualizzazione mappa anima le visualizzazioni correnti e poi la visualizzazione personalizzata. L'intestazione di navigazione deve essere visibile per consentire la visualizzazione della vista personalizzata.

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

Se la visualizzazione deve cambiare dimensioni in qualsiasi momento, puoi chiamare invalidateLayoutForAccessoryView:, passando la visualizzazione di cui deve essere modificata la dimensione.

Esempio

Il seguente esempio di codice mostra una visualizzazione personalizzata che implementa il protocolloGMSNavigationAccessoryView. Questa vista personalizzata viene poi utilizzata per impostare una vista accessoria dell'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 di indicazioni

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

  1. Attiva un pulsante del punto di contatto 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 contatto, crea un GMSNavigationDirectionsListController (controller) con il navigatore associato al GMSMapView (mapView).
  3. Aggiungi il controller a un'istanza di UIViewController (view controller) e aggiungi directionsListView come visualizzazione secondaria del view controller. I metodi reloadData e invalidateLayout sul controller devono essere chiamati come per un UICollectionView.
  4. Inserisci il controller della vista nella gerarchia dei controller della vista dell'app.

Il seguente esempio di codice 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 viaggio

La barra di avanzamento del viaggio aggiunta alla navigazione.

La barra di avanzamento del viaggio è una barra verticale che viene visualizzata sul lato destro della mappa quando inizia la navigazione. Se è attiva, viene visualizzata una panoramica di un intero viaggio, insieme alla destinazione e alla posizione corrente dell'utente.

Consente agli utenti di anticipare rapidamente eventuali problemi imminenti, come il traffico, senza dover aumentare lo zoom. Se necessario, può cambiare il percorso della corsa. Se l'utente cambia il percorso della corsa, la barra di avanzamento viene reimpostata come se da quel punto fosse iniziata una nuova corsa.

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

  • Stato del traffico: lo stato del traffico che si trova davanti.

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

  • Percorso trascorso: la parte del viaggio trascorsa.

Attiva la barra di avanzamento del viaggio 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 in mapView. Con questa funzionalità, l'utente può attivare la visualizzazione di icone di semafori o segnali di stop lungo il percorso, fornendo un contesto migliore per viaggi più efficienti e accurati.

Per impostazione predefinita, i semafori e i segnali di stop sono disattivati nell'SDK Navigation per iOS. Per attivare questa funzionalità, chiama le impostazioni 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 Guida, l'SDK Navigation per iOS mostra un controllo del limite di velocità nell'angolo in basso della mappa che indica il limite di velocità corrente. Quando il conducente supera il limite di velocità, il controllo si espande per mostrare un secondo tachimetro con la velocità attuale del conducente.

Puoi impostare i livelli di avviso per modificare la formattazione del display del tachimetro quando il conducente supera il limite di velocità di un valore specificato. Ad esempio, puoi specificare che la velocità attuale venga visualizzata con un colore di testo rosso quando il guidatore 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 saperne di più su come impostare gli avvisi per il tachimetro, consulta Configurare gli avvisi del 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à dell'esperienza con le mappe

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

Disattivare i gesti della 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 tramite programmazione. Tieni presente che la disattivazione del gesto non limita l'accesso programmatico alle impostazioni della fotocamera.

  • scrollGestures: consente di stabilire se i gesti di scorrimento sono attivati o disattivati. Se questa opzione è attiva, gli utenti possono scorrere per eseguire la panoramica della videocamera.
  • zoomGestures: consente di stabilire se i gesti di zoom sono attivati o disattivati. Se questa opzione è attiva, gli utenti possono fare un doppio tocco, toccare con due dita o pizzicare per aumentare o diminuire lo zoom della videocamera. Tieni presente che se tocchi due volte o pizzichi quando scrollGestures sono attivati, la videocamera potrebbe eseguire la panoramica fino al punto specificato.
  • tiltGestures: consente di stabilire se i gesti di inclinazione sono attivati o disattivati. Se questa opzione è attiva, gli utenti possono inclinare la fotocamera con uno scorrimento verticale verso l'alto o verso il basso con due dita.
  • rotateGestures: consente di stabilire se i gesti di rotazione sono attivati o disattivati. Se questa opzione è attiva, gli utenti possono ruotare la fotocamera con un gesto di rotazione con due dita.

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

Swift

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

Objective-C

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

Posiziona i controlli e gli elementi dell'interfaccia utente

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

  • navigationHeaderLayoutGuide
  • navigationFooterLayoutGuide

Il seguente esempio di codice mostra come utilizzare le guide di 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;

Nascondere i percorsi alternativi

Quando l'interfaccia utente è troppo ingombrata da troppe informazioni, puoi ridurre il numero di percorsi alternativi rispetto a quelli predefiniti (due) o non mostrare alcun percorso alternativo. Puoi configurare questa opzione prima di recuperare i percorsi configurando GMSNavigationRoutingOptions e impostando alternateRoutesStrategy su uno dei seguenti valori di enumerazione:

Valore di enumerazioneDescrizione
GMSNavigationAlternateRoutesStrategyAll Predefinita. Mostra fino a due percorsi alternativi.
GMSNavigationAlternateRoutesStrategyOne Mostra 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){...}];