Con el SDK de Navigation para iOS, puedes modificar la experiencia del usuario con tu mapa determinando qué controles y elementos integrados de la IU aparecen en el mapa, y qué gestos permites. También puedes modificar el aspecto visual de la IU de Navigation. Consulta la página de políticas para obtener instrucciones sobre las modificaciones aceptables en la IU de navegación.
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 de inmediato 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. Cuando el usuario hace clic en la brújula, la cámara vuelve a una posición con un rumbo de cero (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 como "Seguir", la brújula permanece visible y, si la presionas, se alterna entre las perspectivas de cámara inclinada y de vista general.
Para evitar que el conductor se distraiga, la brújula permanece en la misma posición si el encabezado (en modo vertical) se expande y entra en conflicto con la posición predeterminada de la brújula. Si agregas un control personalizado de encabezado secundario o una vista de accesorio de encabezado, la brújula se oculta para evitar conflictos en la IU.
La brújula admite los modos diurno y nocturno, así como el modo oscuro.
La brújula viene desactivada de manera predeterminada. Puedes habilitar la brújula configurando la propiedad compassButton
de GMSUISettings
como true
. 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 solo cuando está habilitado. Cuando un usuario hace clic en el botón, la cámara se anima para enfocarse en la ubicación actual del usuario si se conoce. Puedes habilitar el botón configurando la propiedad myLocationButton
de GMSUISettings
como true
.
Swift
mapView.settings.myLocationButton = true
Objective-C
mapView.settings.myLocationButton = YES;
Botón para volver a centrar
Cuando se habilita la navegación, el botón para volver a centrar el mapa aparece cuando el usuario se desplaza por la vista del mapa y desaparece cuando el usuario presiona para volver a centrar el mapa. Para permitir que aparezca el botón de centrado, establece la propiedad recenterButtonEnabled
de GMSUISettings
en true
. Para evitar que aparezca el botón de centrado, establece recenterButtonEnabled
en false
.
Swift
mapView.settings.isRecenterButtonEnabled = true
Objective-C
mapView.settings.recenterButtonEnabled = YES;
Accesorios de la IU del mapa
El SDK de Navigation proporciona accesorios de la IU que aparecen durante la navegación, similares a los que se encuentran en la aplicación de Google Maps para iOS. Puedes ajustar la visibilidad o la apariencia visual de estos controles como se describe en esta sección. Los cambios que realices aquí se reflejarán en el próximo viaje del usuario.
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 pie de página de navegación aparece 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. El pie de navegación muestra el tiempo y la distancia estimados hasta el destino, así como la hora de llegada estimada.
Puedes activar o desactivar la visibilidad del encabezado y el pie de navegación, y establecer sus colores de forma programática con las siguientes propiedades:
navigationHeaderEnabled
: Controla si el encabezado de navegación está visible (el valor predeterminado estrue
).navigationFooterEnabled
: Controla si el pie de página de navegación está 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, establecer 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 de encabezado del accesorio de navegación
Puedes personalizar tu app reemplazando la vista del encabezado de navegación secundaria por tu propia vista de accesorio personalizada. 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 el mapa proporcionado, y debes indicar la altura que requiere tu vista.
Luego, puedes pasar esta vista a mapView llamando a setHeaderAccessoryView:
. La vista de mapa muestra una animación de salida de las vistas actuales y, luego, muestra una animación de entrada de tu vista personalizada. El encabezado de navegación debe estar visible para que se muestre tu vista personalizada.
Para quitar la vista de accesorio del encabezado personalizado, pasa nil
a setHeaderAccessoryView:
.
Si tu vista debe cambiar de tamaño en cualquier momento, puedes llamar a invalidateLayoutForAccessoryView:
y pasar la vista que necesita 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];
Modo nocturno
El método de escucha GMSNavigatorListener.didChangeSuggestedLightingMode
se activa cuando se actualizan las condiciones de iluminación estimadas. Por ejemplo, cuando cae la noche en la ubicación actual del dispositivo. Puedes modificar el comportamiento del modo nocturno de forma programática de las siguientes maneras:
- Elige cuándo se usan los modos normal y de baja luminosidad (nocturno) con el enum
GMSNavigationLightingMode
. - Selecciona los colores de fondo principal y secundario del modo nocturno configurando los valores de las propiedades
navigationHeaderPrimaryBackgroundColorNightMode
ynavigationHeaderSecondaryBackgroundColorNightMode
.
Lista de instrucciones sobre cómo llegar
Puedes proporcionar instrucciones paso a paso en tu app. En el siguiente ejemplo, se muestra una forma 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
setDestinations
en elGMSNavigator
(navegador) se haya completado correctamente y se haya habilitadoguidanceActive
en el navegador. - Cuando un usuario presiona el botón de punto de entrada, crea un
GMSNavigationDirectionsListController
(controlador) con el navegador asociado alGMSMapView
(mapView
). - Agrega el controlador a una instancia de
UIViewController
(controlador de vista) y agrega eldirectionsListView
como una subvista del controlador de vista. Los métodosreloadData
yinvalidateLayout
del controlador se deben llamar como si se tratara de unUICollectionView
. - Envía el controlador de vista a la jerarquía de controladores de vista 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)
// Make sure 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];
// Make sure 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 lado inicial o principal del mapa cuando se inicia la navegación. Cuando está habilitada, muestra un resumen de todo el viaje, junto con el destino y la posición actual del usuario.
Esto les permite a los usuarios anticipar rápidamente cualquier problema próximo, como el tráfico, sin necesidad de acercar la imagen. Luego, puede cambiar la ruta del viaje si es necesario. Si el usuario cambia la ruta del viaje, la barra de progreso se restablece como si se hubiera iniciado un viaje nuevo desde ese punto.
La barra de progreso del viaje muestra los siguientes indicadores de estado:
Estado del tráfico: Es el estado del tráfico próximo.
Ubicación actual: Es la ubicación actual del conductor durante el viaje.
Route elapsed: Es la parte transcurrida del viaje.
Habilita la barra de progreso del viaje configurando la propiedad navigationTripProgressBarEnabled
en GMSUISettings.
Swift
mapView.settings.isNavigationTripProgressBarEnabled = true
Objective-C
mapView.settings.navigationTripProgressBarEnabled = YES;
Posicionamiento de la barra de progreso del viaje
- El lado izquierdo de la barra se alinea aproximadamente con el lado izquierdo del velocímetro, el logotipo de Google y el botón Volver a centrar (cuando está visible). El ancho es de 12 pt.
- La barra de progreso del viaje responde de forma dinámica al espacio vertical de la pantalla. La parte inferior de la barra se ubica a 210 pt de la parte inferior de la pantalla. La parte superior de la barra de progreso del viaje permanece a al menos 170 pt de la parte superior de la pantalla, con una altura máxima de la barra de 400 pt.
- Si la barra de progreso del viaje se superpone con la tarjeta de giros o con otros elementos de la IU de Navegación, aparecerá debajo de esos otros elementos.
API de Prompt Visibility (experimental)
La API de Prompt Visibility te permite evitar conflictos entre los elementos de la IU generados por el SDK de Navigation y tus propios elementos de la IU personalizados agregando un objeto de escucha para recibir una devolución de llamada antes de que aparezca un elemento de la IU del SDK de Navigation y tan pronto como se quite el elemento. Para obtener más información, incluidas muestras de código, consulta la sección de la API de Prompt Visibility en la página Configura interrupciones en tiempo real.
Semáforos y señales de alto
Puedes habilitar la visualización de semáforos y señales de alto durante la navegación activa en mapView
, lo que proporciona contexto adicional para las rutas y las maniobras del viaje.
De forma predeterminada, los semáforos y las 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 = true
mapView.settings.showsStopSigns = true
Objective-C
mapView.settings.showsTrafficLights = YES;
mapView.settings.showsStopSigns = YES;
Control del velocímetro
Cuando se habilita la navegación y el modo de viaje se establece en conducción, 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 establecer niveles de alerta para cambiar el formato de la pantalla del velocímetro cuando el conductor exceda el límite de velocidad en una cantidad específica. Por ejemplo, puedes especificar que la velocidad actual se muestre con un color de texto rojo cuando el conductor supere el límite de velocidad en 8 km/h y con un color de fondo rojo cuando lo supere en 16 km/h.
Para mostrar el control de límite de velocidad, establece la propiedad shouldDisplaySpeedometer
de GMSUISettings
en true
. Para inhabilitar la visualización del control de límite de velocidad, establece shouldDisplaySpeedometer
en false
.
Swift
mapView.shouldDisplaySpeedometer = true
Objective-C
mapView.shouldDisplaySpeedometer = YES;
Para obtener más información sobre cómo configurar alertas para el velocímetro, consulta Cómo configurar alertas del velocímetro.
Marcadores de destino
Puedes mostrar u ocultar los marcadores de destino de una ruta determinada configurando la propiedad showsDestinationMarkers
de GMSUISettings
. 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 el mapa
El SDK de Navigation te permite personalizar aún más la experiencia de navegación para tus usuarios. Los cambios que realices en tu instancia se reflejarán en la próxima actualización de tu app por parte del usuario.
Destacado de destinos y entradas
Cuando se crea un destino con un placeID
, se destacará el edificio del destino y se mostrará un ícono de entrada siempre que sea posible. Estas señales visuales ayudan a los usuarios a distinguir su destino y navegar hacia él.
Para crear un destino con un placeID
, usa uno de los inicializadores de GMSNavigationWaypoint
que acepte un placeID
. Por ejemplo, los destinos creados en el instructivo sobre cómo navegar por una ruta incluyen el resaltado del destino y las etiquetas de entrada cuando están disponibles.
Inhabilita los gestos predeterminados del mapa
Puedes inhabilitar los gestos predeterminados en el mapa configurando 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 acercar la cámara. Ten en cuenta que, si presionas dos veces o pellizcas la pantalla cuandoscrollGestures
están habilitados, es posible que la cámara se desplace horizontalmente 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 verticalmente hacia arriba o hacia abajo 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 podrán usar un gesto de rotación con dos dedos para rotar la cámara.
En este ejemplo, se inhabilitaron los gestos de desplazamiento 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 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 con las siguientes propiedades:
navigationHeaderLayoutGuide
navigationFooterLayoutGuide
bottomTrailingButtonsLayoutGuide
En el siguiente ejemplo de código, se muestra el uso de las guías de diseño para posicionar un par de etiquetas en la vista del 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;
Para ver un ejemplo de cómo usar un bottomTrailingButtonsLayoutGuide
para colocar el botón de informes de interrupciones en tiempo real, consulta Configura las interrupciones en tiempo real.
Cómo ocultar rutas alternativas
Cuando la interfaz de usuario se sobrecarga con demasiada información, puedes reducir el desorden mostrando menos rutas alternativas que las predeterminadas (dos) o no mostrando ninguna ruta alternativa. Puedes configurar esta opción antes de recuperar las rutas configurando GMSNavigationRoutingOptions
y estableciendo alternateRoutesStrategy
con uno de los siguientes valores de enumeración:
Valor de enumeración | Descripción |
---|---|
GMSNavigationAlternateRoutesStrategyAll | Predeterminado. Muestra hasta dos rutas alternativas. |
GMSNavigationAlternateRoutesStrategyOne | Muestra una ruta alternativa (si hay una disponible). |
GMSNavigationAlternateRoutesStrategyNone | Oculta las 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){...}];