Con el SDK de Navigation para iOS, puedes modificar la experiencia del usuario con tu mapa. Para ello, determina qué controles y elementos de la IU integrados aparecerán en el mapa y qué gestos permitirás. También puedes modificar el aspecto visual de la IU de Navigation. Consulta la página de políticas para obtener lineamientos sobre las modificaciones aceptables de la IU de Navigation.
Controles de la IU del mapa
El SDK de Navigation proporciona algunos controles de IU integrados similares a los de 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 determinadas circunstancias y solo cuando está habilitado. La brújula solo aparece cuando la cámara se orienta de modo que tenga 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 de cero (la orientación predeterminada), y la brújula se desvanece poco después.
Si la navegación está habilitada y el modo de cámara está configurado en "siguiendo", el compás permanece visible y, si lo presionas, se alterna entre las perspectivas de la cámara inclinada y general.
La brújula viene desactivada de manera predeterminada. Puedes habilitar la brújula configurando la propiedad compassButton
de GMSUISettings
en 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 solamente cuando se habilita el botón correspondiente. Cuando un usuario hace clic en el botón, la cámara se anima para enfocar la ubicación actual del usuario si esta ubicación se conoce en el momento. 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 el mapa
Cuando la navegación está habilitada, 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 recentrar, establece la propiedad recenterButtonEnabled
de GMSUISettings
en true
. Para evitar que aparezca el botón de recentrar, 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 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 usuario.
Encabezado y pie de página de Navigation
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 siguiente giro. El pie de página de navegación muestra la hora estimada y la distancia 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 configurar 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 del 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 del encabezado del accesorio de navegación
Para personalizar tu app, reemplaza la vista del encabezado de navegación secundario con 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 mapView determinado y debes proporcionar la altura que requiere tu vista.
Luego, puedes pasar esta vista a mapView llamando a setHeaderAccessoryView:
. Esta función anima las vistas actuales y, luego, anima tu vista personalizada. El encabezado de navegación debe ser visible para que se muestre tu vista personalizada.
Para quitar la vista del accesorio de 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];
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 implementación.
- Habilita un botón de punto de entrada después de que
setDestinations
enGMSNavigator
(navegador) se haya completado correctamente y se haya habilitadoguidanceActive
en el navegador. - Cuando un usuario presiona el botón de punto de entrada, se crea un
GMSNavigationDirectionsListController
(controlador) con el navegador asociado con elGMSMapView
(mapView
). - Agrega el controlador a una instancia de
UIViewController
(controlador de vista) y agrega eldirectionsListView
como una vista secundaria del controlador de vista. Se debe llamar a los métodosreloadData
yinvalidateLayout
del controlador como lo harías con 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)
// 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 del mapa cuando comienza la navegación. Cuando está habilitado, muestra un resumen de un viaje completo, junto con el destino y la posición actual del usuario.
Les permite a los usuarios anticipar rápidamente cualquier problema, 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 que se aproxima.
Ubicación actual: Es la ubicación actual del conductor en el viaje.
Recorrido transcurrido: Es la parte del viaje transcurrido.
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 detención
Puedes habilitar los semáforos y las señales de detención en mapView
. Con esta función, el usuario puede habilitar la visualización de semáforos o íconos de señales de detención 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 los carteles 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 la navegación está habilitada y el modo de viaje está configurado en conducir, 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 supere el límite de velocidad en una cantidad especificada. 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 supere el límite de velocidad 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 del mapa
El SDK de Navigation te permite realizar más personalizaciones en la experiencia de navegación de tus usuarios. Los cambios que realices en tu instancia se reflejarán durante la próxima actualización de la app por parte del usuario.
Inhabilita los gestos predeterminados del mapa
Puedes deshabilitar los gestos predeterminados en el mapa configurando las propiedades de la clase GMSUISettings
, que se encuentra disponible como propiedad de GMSMapView
.
Los siguientes gestos pueden habilitarse y deshabilitarse de manera programática. Ten en cuenta que, si inhabilitas el gesto, no se 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 habilitan, los usuarios pueden aplicar dos toques, toques con dos dedos o usar dos dedos para aplicar zoom a la cámara. Ten en cuenta que, cuando están habilitados losscrollGestures
, el toque doble o el acercamiento de dedos pueden desplazar la cámara hasta el punto especificado.tiltGestures
: Controla si los gestos de inclinación están habilitados o inhabilitados. Si se habilitan, los usuarios pueden deslizar dos dedos hacia arriba o abajo para inclinar la cámara.rotateGestures
: Controla si los gestos de rotación están habilitados o inhabilitados. Si se habilitan, los usuarios pueden realizar gestos de rotación con dos dedos para girar la cámara.
En este ejemplo, se desactivaron 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 posicionar 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 mediante 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 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;
Cómo ocultar las rutas alternativas
Cuando la interfaz de usuario se llena de 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. Para ello, configura GMSNavigationRoutingOptions
y 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){...}];