Con el SDK de Navigation para iOS, puedes modificar la experiencia del usuario con tu mapa si determinas qué controles y elementos integrados de la IU aparecerán en el mapa, y qué gestos permitirás. También puedes modificar la apariencia visual de la IU de Navigation. Consulta la página Políticas para obtener lineamientos sobre las modificaciones aceptables en la IU de Navigation.
Controles de la IU del mapa
El SDK de Navigation proporciona algunos controles de la IU integrados similares a los que se encuentran en la aplicación de Google Maps para iOS. Puedes activar o desactivar la visibilidad de estos controles con la clase GMSUISettings
.
Los cambios que realices en esta clase se reflejarán inmediatamente en el mapa.
Brújula
El SDK de Navigation proporciona un gráfico de brújula que aparece en la esquina superior derecha del mapa en ciertas circunstancias y solo cuando está habilitado. La brújula solo aparece cuando la cámara se orienta de modo que tiene un rumbo distinto del norte exacto (un rumbo distinto de cero). Cuando el usuario hace clic en la brújula, la cámara vuelve a animarse y se ubica en una posición con un rumbo igual a cero (es decir, la orientación predeterminada) y la brújula se atenúa poco después.
Si la navegación está habilitada y el modo de cámara está configurado en "Siguiendo", la brújula seguirá visible y si presionas la brújula para alternar entre las perspectivas de la cámara inclinada y de vista general.
La brújula viene desactivada de manera predeterminada. Para habilitar la brújula, establece la propiedad compassButton
de GMSUISettings
en YES
. Sin embargo, no puedes forzar su aparición en todo momento.
Swift
mapView.settings.compassButton = true
Objective‑C
mapView.settings.compassButton = YES;
Botón Mi ubicación
El botón Mi ubicación aparece en la esquina inferior derecha de la pantalla solamente cuando está habilitado. Cuando un usuario hace clic en el botón, se anima la cámara para enfocarse en la ubicación actual del usuario si esta se conoce en ese momento. Para habilitar el botón, configura la propiedad myLocationButton
de GMSUISettings
como YES
.
Swift
mapView.settings.myLocationButton = true
Objective‑C
mapView.settings.myLocationButton = YES;
Botón para volver a centrar
Cuando la navegación está habilitada, el botón para volver a centrar el mapa aparece cuando el usuario se desplaza por la vista de mapa y desaparece cuando el usuario presiona para volver a centrar el mapa. Para permitir que aparezca el botón de volver a centrar, establece la propiedad recenterButtonEnabled
de GMSUISettings
en YES
. Para evitar que aparezca el botón de volver a centrar, establece recenterButtonEnabled
en NO
.
Swift
mapView.settings.isRecenterButtonEnabled = true
Objective‑C
mapView.settings.recenterButtonEnabled = YES;
Accesorios de IU de mapas
El SDK de Navigation proporciona accesorios de IU que aparecen durante la navegación de manera similar a los que se encuentran en la aplicación de Google Maps para iOS. Puedes ajustar la visibilidad o el aspecto visual de estos controles como se describe en esta sección. Los cambios que realices aquí se reflejarán durante el próximo viaje del conductor.
Encabezado y pie de página de navegación
Durante la navegación, el encabezado de navegación aparece en la parte superior de la pantalla y el de navegación en la parte inferior. El encabezado de navegación muestra el nombre de la calle y la dirección del próximo giro en la ruta, así como la dirección del giro siguiente. En el pie de página de navegación, se muestran la hora y la distancia estimadas hasta el destino, así como la hora estimada de llegada.
Puedes activar o desactivar la visibilidad del encabezado y el pie de página de navegación, y establecer sus colores de manera programática con las siguientes propiedades:
navigationHeaderEnabled
: Controla si el encabezado de navegación es visible (el valor predeterminado estrue
).navigationFooterEnabled
: Controla si el pie de página de navegación es visible (el valor predeterminado estrue
).navigationHeaderPrimaryBackgroundColor
: Establece el color de fondo principal para el encabezado de navegación.navigationHeaderSecondaryBackgroundColor
: Establece el color de fondo secundario para el encabezado de navegación.
En el siguiente ejemplo de código, se muestra cómo activar la visibilidad del encabezado y el pie de página, y luego configurar navigationHeaderPrimaryBackgroundColor
en azul y navigationHeaderSecondaryBackgroundColor
en rojo.
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];
Vista del encabezado del accesorio de navegación
Para personalizar tu app, reemplaza la vista del encabezado de navegación secundaria por tu propia vista personalizada de accesorios. Para ello, crea una vista que implemente el protocolo GMSNavigationAccessoryView
. Este protocolo tiene un método obligatorio: -heightForAccessoryViewConstrainedToSize:onMapView:
. Se te proporciona el tamaño máximo disponible para tu vista en una vista de mapa determinada y debes proporcionar la altura que requiere tu vista.
Luego, puedes pasar esta vista a mapView llamando a setHeaderAccessoryView:
. MapView anima cualquier vista actual y, luego, anima en tu vista personalizada. El encabezado de navegación debe ser visible para que se pueda mostrar tu vista personalizada.
Para quitar la vista de accesorio de encabezado personalizado, pasa nil
a setHeaderAccessoryView:
.
Si la vista debe cambiar de tamaño en cualquier momento, puedes llamar a invalidateLayoutForAccessoryView:
y pasar la vista que debe cambiar de tamaño.
Ejemplo
En el siguiente ejemplo de código, se muestra una vista personalizada que implementa el protocolo GMSNavigationAccessoryView
. Luego, esta vista personalizada se usa para establecer una vista de accesorio de encabezado de navegación personalizada.
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];
Lista de instrucciones sobre cómo llegar
Puedes proporcionar instrucciones paso a paso en tu app. En el siguiente ejemplo, se muestra una manera posible de hacerlo. Estos pasos pueden variar según tu propia implementación.
- Habilita un botón de punto de entrada después de que se haya completado correctamente
setDestinations
enGMSNavigator
(navegador) y se haya habilitadoguidanceActive
en el navegador. - Cuando un usuario presione el botón de punto de entrada, crea un
GMSNavigationDirectionsListController
(controlador) con el navegador asociado conGMSMapView
(mapView
). - Agrega el controlador a una instancia de
UIViewController
(controlador de vista) y agregadirectionsListView
como una subvista del controlador de vista. Los métodosreloadData
yinvalidateLayout
del controlador deben llamarse como se haría con unUICollectionView
. - Envía el controlador de vista a la jerarquía de estos controladores de la app.
En el siguiente ejemplo de código, se muestra cómo agregar 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 de progreso del viaje
La barra de progreso del viaje es una barra vertical que aparece en el borde derecho final del mapa cuando comienza la navegación. Cuando se habilita, muestra una descripción general de todo el viaje, junto con el destino del conductor y su posición actual.
Proporciona a los conductores la capacidad de anticipar con rapidez cualquier problema futuro, como el tráfico, sin necesidad de acercar la imagen. Luego, pueden redirigir el viaje si es necesario. Si el conductor redirecciona el viaje, la barra de progreso se restablece como si comenzara un nuevo viaje desde ese punto.
La barra de progreso del viaje muestra los siguientes indicadores de estado:
Estado del tráfico: El estado del tráfico próximo.
Ubicación actual: La ubicación actual del conductor en el viaje.
Ruta transcurrida: La parte transcurrida del viaje.
Para habilitar la barra de progreso del viaje, configura la propiedad navigationTripProgressBarEnabled
en GMSUISettings.
Swift
mapView.settings.isNavigationTripProgressBarEnabled = true
Objective‑C
mapView.settings.navigationTripProgressBarEnabled = YES;
Semáforos y señales de alto
Puedes habilitar los semáforos y las señales de alto en mapView
. Con esta función, el conductor puede habilitar la visualización de semáforos o íconos de señales de alto a lo largo de su ruta, lo que proporciona un mejor contexto para viajes más eficientes y precisos.
De forma predeterminada, los semáforos y señales de alto están inhabilitados en el SDK de Navigation para iOS. Para habilitar esta función, llama a la configuración de GMSMapView
para cada opción de forma independiente: showsTrafficLights
y showsStopSigns
.
Swift
mapView.settings.showsTrafficLights = YES;
mapView.settings.showsStopSigns = YES;
Objective‑C
mapView.settings.showsTrafficLights = true;
mapView.settings.showsStopSigns = true;
Control del velocímetro
Cuando la navegación está habilitada, el SDK de Navigation para iOS muestra un control de límite de velocidad en la esquina inferior del mapa que muestra el límite de velocidad actual. Cuando el conductor supera el límite de velocidad, el control se expande para mostrar un segundo velocímetro con la velocidad actual del conductor.
Puedes configurar niveles de alerta para cambiar el formato de la pantalla del velocímetro cuando el conductor excede el límite de velocidad en una cantidad específica. Por ejemplo, puedes especificar que la velocidad actual se muestre con un texto de color rojo cuando el conductor exceda el límite de velocidad en 8 km/h y con un color de fondo rojo cuando el conductor lo supere en 16 km/h.
Para mostrar el control de límite de velocidad, establece la propiedad shouldDisplaySpeedometer
de GMSUISettings
en YES
. Para inhabilitar la visualización del control de límite de velocidad, establece shouldDisplaySpeedometer
en NO
.
Swift
mapView.shouldDisplaySpeedometer = true
Objective‑C
mapView.shouldDisplaySpeedometer = YES;
Si quieres obtener más información para configurar alertas del velocímetro, consulta Configura alertas del velocímetro.
Marcadores de destino
Puedes configurar la propiedad showsDestinationMarkers
de GMSUISettings
para mostrar u ocultar los marcadores de destino de una ruta determinada. En el siguiente ejemplo, se muestra cómo desactivar los marcadores de destino.
Swift
mapView.settings.showsDestinationMarkers = false
Objective‑C
mapView.settings.showsDestinationMarkers = NO;
Funciones de la experiencia en Maps
El SDK de Navigation te permite personalizar aún más la experiencia de navegación de tus usuarios. Los cambios que realizas en tu instancia se reflejan durante la próxima actualización del controlador de tu app.
Cómo inhabilitar los gestos de mapa predeterminados
Puedes inhabilitar los gestos predeterminados en el mapa si configuras las propiedades de la clase GMSUISettings
, que está disponible como propiedad de GMSMapView
.
Los siguientes gestos pueden habilitarse y deshabilitarse de manera programática. Ten en cuenta que inhabilitar el gesto no limitará el acceso programático a la configuración de la cámara.
scrollGestures
: Controla si los gestos de desplazamiento están habilitados o inhabilitados. Si se habilitan, los usuarios pueden deslizar el dedo para desplazar la cámara.zoomGestures
: Controla si los gestos de zoom están habilitados o inhabilitados. Si se habilita esta opción, los usuarios pueden presionar dos veces, presionar con dos dedos o pellizcar para hacer zoom en la cámara. Ten en cuenta que presionar dos veces o pellizcar cuando losscrollGestures
están habilitados puede desplazar la cámara hasta el punto especificado.tiltGestures
: Controla si los gestos de inclinación están habilitados o inhabilitados. Si se habilita esta opción, los usuarios pueden deslizar dos dedos hacia abajo o hacia arriba para inclinar la cámara.rotateGestures
: Controla si los gestos de rotación están habilitados o inhabilitados. Si se habilita esta opción, los usuarios pueden usar un gesto de rotación con dos dedos para rotar la cámara.
En este ejemplo, se inhabilitaron los gestos de desplazamiento lateral y zoom.
Swift
mapView.settings.scrollGestures = false
mapView.settings.zoomGestures = false
Objective‑C
mapView.settings.scrollGestures = NO;
mapView.settings.zoomGestures = NO;
Controles de posición y elementos de la IU
Puedes colocar los controles y otros elementos de la IU en relación con la posición del encabezado y el pie de página de navegación usando las siguientes propiedades:
navigationHeaderLayoutGuide
navigationFooterLayoutGuide
En el siguiente ejemplo de código, se muestra cómo usar las guías de diseño para posicionar un par de etiquetas en la vista de mapa:
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;
Ocultar rutas alternativas
Cuando la interfaz de usuario se satura con demasiada información, puedes reducir la sobrecarga si muestras menos rutas alternativas que las predeterminadas (dos) o no muestras ninguna ruta alternativa. Puedes configurar esta opción antes de recuperar las rutas. Para ello, configura GMSNavigationRoutingOptions
y establece alternateRoutesStrategy
con uno de los siguientes valores de enumeración:
Valor de enumeración | Descripción |
---|---|
GMSNavegaciónAlternativaDeRutasEstrategiaTodo | Predeterminado. Muestra hasta dos rutas alternativas. |
GMSNavegaciónAlternativaDeRutasEstrategiaOne | Muestra una ruta alternativa (si hay una disponible). |
GMSNavigationAlternateRoutesStrategyNone | Oculta rutas alternativas. |
Ejemplo
En el siguiente ejemplo de código, se muestra cómo ocultar las rutas alternativas por completo.
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){...}];