Za pomocą pakietu SDK nawigacji na iOS możesz zmodyfikować sposób wyświetlania mapy, określając, które z wbudowanych elementów sterujących i elementów interfejsu mają się na niej pojawiać oraz które gesty mają być obsługiwane. Możesz też zmienić wygląd wizualny interfejsu nawigacji. Wskazówki dotyczące dozwolonych modyfikacji interfejsu nawigacji znajdziesz na stronie zasad.
Elementy sterujące mapy
Pakiet SDK do nawigacji udostępnia wbudowane elementy sterujące interfejsem użytkownika podobne do tych, które występują w aplikacji Mapy Google na iOS. Możesz włączać i wyłączać widoczność tych elementów sterujących za pomocą klasy GMSUISettings
.
Zmiany wprowadzone w tej klasie są od razu widoczne na mapie.
Kompas
Pakiet SDK nawigacji udostępnia grafikę kompasu, która w określonych okolicznościach i tylko wtedy, gdy jest włączona, pojawia się w prawym górnym rogu mapy. Kompas pojawia się tylko wtedy, gdy kamera jest ustawiona w taki sposób, że ma kierunek inny niż dokładnie na północ (kierunek niezerowy). Gdy użytkownik kliknie kompas, kamera powróci do pozycji z kierunkiem 0 stopni (orientacja domyślna), a kompas zniknie po chwili.
Jeśli nawigacja jest włączona, a tryb kamery ustawiony na „Podążanie”, kompas pozostaje widoczny. Kliknięcie kompasu powoduje przełączenie się między perspektywą z wykrzywionego i panoramy.
Kompas jest domyślnie wyłączony. Możesz włączyć kompas, ustawiając właściwość compassButton
w elementach GMSUISettings
na true
. Nie możesz jednak wymusić wyświetlania kompasu przez cały czas.
Swift
mapView.settings.compassButton = true
Objective-C
mapView.settings.compassButton = YES;
Przycisk Moja lokalizacja
Przycisk Moja lokalizacja pojawia się w prawym dolnym rogu ekranu tylko, gdy jest włączony. Gdy użytkownik kliknie przycisk, kamera wykona animację, aby ustawić ostrość na jego bieżącej lokalizacji (jeśli jest ona znana). Możesz włączyć przycisk, ustawiając właściwość myLocationButton
w elementach GMSUISettings
na true
.
Swift
mapView.settings.myLocationButton = true
Objective-C
mapView.settings.myLocationButton = YES;
Przycisk Wyśrodkuj
Gdy nawigacja jest włączona, przycisk wyśrodkowania pojawia się, gdy użytkownik przewija widok mapy, i znika, gdy użytkownik klika, aby ponownie wyśrodkować mapę. Aby umożliwić wyświetlanie przycisku przybliżania, ustaw właściwość recenterButtonEnabled
w elementach GMSUISettings
na true
. Aby zapobiec wyświetlaniu przycisku recentera, ustaw recenterButtonEnabled
jako false
.
Swift
mapView.settings.isRecenterButtonEnabled = true
Objective-C
mapView.settings.recenterButtonEnabled = YES;
Akcesoria mapy w interfejsie
Pakiet SDK do nawigacji udostępnia elementy interfejsu, które pojawiają się podczas nawigacji i są podobne do tych, które można znaleźć w aplikacji Mapy Google na iOS. Możesz dostosować widoczność lub wygląd tych elementów sterujących zgodnie z opisem w tej sekcji. Zmiany, które tu wprowadzisz, będą widoczne w przyszłej podróży użytkownika.
Nagłówek i stopka nawigacji
Podczas nawigacji nagłówek nawigacji pojawia się u góry ekranu, a stopka nawigacji – u dołu. W nagłówku nawigacji wyświetlana jest nazwa ulicy i kierunek następnego skrętu na trasie, a także kierunek następnego skrętu. W stopce nawigacji wyświetla się szacowany czas i odległość do miejsca docelowego oraz szacowany czas przyjazdu.
Możesz włączać i wyłączać widoczność nagłówka i stopki nawigacji oraz ustawiać ich kolory za pomocą tych właściwości:
navigationHeaderEnabled
– określa, czy nagłówek nawigacji jest widoczny (wartość domyślna totrue
).navigationFooterEnabled
– określa, czy stopka nawigacji jest widoczna (wartość domyślna totrue
).navigationHeaderPrimaryBackgroundColor
– ustawia podstawowy kolor tła nagłówka nawigacji.navigationHeaderSecondaryBackgroundColor
– ustawia dodatkowy kolor tła nagłówka nawigacji.
Poniższy przykład kodu pokazuje włączenie widoczności nagłówka i stopki, a następnie ustawienie koloru navigationHeaderPrimaryBackgroundColor
na niebiesko, a navigationHeaderSecondaryBackgroundColor
na czerwono.
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];
Widok nagłówka akcesorium nawigacji
Możesz dostosować swoją aplikację, zastępując widok nagłówka z dodatkowym menu nawigacyjnym własnym widokiem akcesorium. Aby to zrobić, utwórz widok danych, który implementuje protokół GMSNavigationAccessoryView
. Ten protokół ma 1 wymagany sposób: -heightForAccessoryViewConstrainedToSize:onMapView:
. W przypadku danej mapy masz maksymalny dostępny rozmiar widoku. Musisz podać wysokość wymaganą przez widok.
Następnie możesz przekazać ten widok do mapView, wywołując funkcję setHeaderAccessoryView:
. Funkcja mapView powoduje animację wyjścia z bieżących widoków, a następnie animację wejścia do widoku niestandardowego. Aby widok niestandardowy się wyświetlał, nagłówek nawigacji musi być widoczny.
Aby usunąć widok akcesorium nagłówka niestandardowego, prześlij nil
do setHeaderAccessoryView:
.
Jeśli rozmiar widoku musi się zmieniać w dowolnym momencie, możesz wywołać funkcję invalidateLayoutForAccessoryView:
, przekazując widok, którego rozmiar ma się zmienić.
Przykład
Poniższy przykład kodu pokazuje widok niestandardowy, który implementuje protokół GMSNavigationAccessoryView
. Ten widok niestandardowy służy następnie do ustawiania widoku akcesorium nagłówka nawigacji niestandardowej.
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 tras
W aplikacji możesz podać szczegółowe instrukcje. Przykład poniżej pokazuje, jak to zrobić. Te czynności mogą się różnić w zależności od implementacji.
- Włącz przycisk punktu wejścia po zakończeniu działania elementu
setDestinations
w komponencieGMSNavigator
(przewodnik) i włączeniu elementuguidanceActive
w przewodniku. - Gdy użytkownik kliknie przycisk punktu wejścia, utwórz
GMSNavigationDirectionsListController
(kontroler) z nawigatorem powiązanym z elementemGMSMapView
(mapView
). - Dodaj kontroler do instancji
UIViewController
(kontroler widoku) i dodajdirectionsListView
jako podwidok kontrolera widoku. MetodyreloadData
iinvalidateLayout
na kontrolerze powinny być wywoływane tak samo jak w przypadkuUICollectionView
. - Przesuń kontroler widoku w hierarchii kontrolerów widoku aplikacji.
Poniższy przykład kodu pokazuje dodawanie 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];
...
}
...
Pasek postępu podróży
Pasek postępu podróży to pionowy pasek, który pojawia się na prawym skraju mapy po rozpoczęciu nawigacji. Gdy ta opcja jest włączona, wyświetla się przegląd całej podróży wraz z miejscem docelowym i bieżącą pozycją użytkownika.
Umożliwia użytkownikom szybkie przewidywanie nadchodzących problemów, takich jak korki, bez konieczności przybliżania mapy. W razie potrzeby może zmienić trasę przejazdu. Jeśli użytkownik zmieni trasę przejazdu, pasek postępu zostanie zresetowany, tak jakby od tego momentu rozpoczęła się nowa podróż.
Pasek postępu podróży wyświetla te wskaźniki stanu:
Stan ruchu – stan zbliżającego się ruchu.
Bieżąca lokalizacja – bieżąca lokalizacja kierowcy podczas podróży.
Przebyty odcinek trasy – przebyty odcinek trasy.
Aby włączyć pasek postępu podróży, ustaw parametr navigationTripProgressBarEnabled
w ustawieniach GMSUISettings.
Swift
mapView.settings.isNavigationTripProgressBarEnabled = true
Objective-C
mapView.settings.navigationTripProgressBarEnabled = YES;
sygnalizacja świetlna i znaki stopu;
Sygnalizację świetlną i znaki stop możesz włączyć w sekcji mapView
. Dzięki tej funkcji użytkownik może włączyć wyświetlanie na trasie ikon sygnalizacji świetlnej lub znaków stop, co zapewnia lepszy kontekst dla bardziej wydajnych i dokładnych podróży.
Domyślnie sygnalizacja świetlna i znaki stop są wyłączone w pakiecie SDK do nawigacji na iOS. Aby włączyć tę funkcję, wywołaj ustawienia GMSMapView
dla każdej opcji osobno: showsTrafficLights
i showsStopSigns
.
Swift
mapView.settings.showsTrafficLights = true
mapView.settings.showsStopSigns = true
Objective-C
mapView.settings.showsTrafficLights = YES;
mapView.settings.showsStopSigns = YES;
Sterowanie prędkościomierzem
Gdy nawigacja jest włączona, a tryb podróży ustawiony na „Jazda”, w dolnym rogu mapy, na której wyświetla się aktualne ograniczenie prędkości, pakiet Navigation SDK dla iOS wyświetla kontrolkę ograniczenia prędkości. Gdy kierowca przekroczy ograniczenie prędkości, element sterujący rozszerzy się, aby wyświetlić drugi prędkościomierz z aktualną prędkością pojazdu.
Możesz ustawić poziomy alertów, aby zmienić format wyświetlania prędkościomierza, gdy kierowca przekroczy limit prędkości o określoną wartość. Możesz na przykład określić, że bieżąca prędkość wyświetla się w czerwonym kolorze, gdy kierowca przekroczy ograniczenie prędkości o 8 km/h, a w czerwonym tle, gdy przekroczy je o 13 km/h.
Aby wyświetlić kontrolę limitu prędkości, ustaw właściwość shouldDisplaySpeedometer
w elementach GMSUISettings
na true
. Aby wyłączyć wyświetlanie kontroli ograniczenia prędkości, ustaw shouldDisplaySpeedometer
na false
.
Swift
mapView.shouldDisplaySpeedometer = true
Objective-C
mapView.shouldDisplaySpeedometer = YES;
Więcej informacji o ustawianiu alertów dotyczących prędkościomierza znajdziesz w artykule Konfigurowanie alertów prędkościomierza.
znaczniki miejsca docelowego,
Możesz wyświetlać lub ukrywać znaczniki miejsc docelowych na danej trasie, ustawiając właściwość showsDestinationMarkers
w elementach GMSUISettings
. W tym przykładzie pokazano wyłączenie znaczników miejsca docelowego.
Swift
mapView.settings.showsDestinationMarkers = false
Objective-C
mapView.settings.showsDestinationMarkers = NO;
Funkcje mapy
Pakiet SDK nawigacji umożliwia dalsze dostosowywanie nawigacji do potrzeb użytkowników. Zmiany wprowadzone w Twoim wystąpieniu zostaną odzwierciedlone podczas następnej aktualizacji aplikacji przez użytkownika.
Wyłączanie domyślnych gestów na mapie
Domyślne gesty na mapie możesz wyłączyć, ustawiając właściwości klasy GMSUISettings
, która jest dostępna jako właściwość obiektu GMSMapView
.
Te gesty można włączać i wyłączać programowo. Pamiętaj, że wyłączenie gestu nie ograniczy dostępu programowego do ustawień aparatu.
scrollGestures
– określa, czy gesty przewijania są włączone, czy wyłączone. Jeśli ta opcja jest włączona, użytkownicy mogą przesuwać palcem, aby przesuwać kamerę.zoomGestures
– określa, czy gesty powiększania są włączone, czy wyłączone. Jeśli ta opcja jest włączona, użytkownicy mogą dwukrotnie dotknąć ekranu, dotknąć ekranu dwoma palcami lub ująć palcami, aby przybliżyć obraz w aparacie. Pamiętaj, że dwukrotne kliknięcie lub ściąganie, gdy funkcjascrollGestures
jest włączona, może spowodować przewinięcie kamery do określonego punktu.tiltGestures
– określa, czy gesty pochylania są włączone czy wyłączone. Jeśli ta opcja jest włączona, użytkownicy mogą przechylać kamerę, przesuwając 2 palcami w górę lub w dół.rotateGestures
– określa, czy gesty obracania są włączone, czy wyłączone. Jeśli ta opcja jest włączona, użytkownicy mogą obracać kamerę za pomocą gestu obrotu 2 palcami.
W tym przykładzie gesty przesuwania i powiększania zostały wyłączone.
Swift
mapView.settings.scrollGestures = false
mapView.settings.zoomGestures = false
Objective-C
mapView.settings.scrollGestures = NO;
mapView.settings.zoomGestures = NO;
Umieszczenie elementów sterujących i elementów interfejsu
Za pomocą tych właściwości możesz umieszczać elementy sterujące i inne elementy interfejsu względem pozycji nagłówka i stopki nawigacji:
navigationHeaderLayoutGuide
navigationFooterLayoutGuide
Ten przykład kodu pokazuje, jak za pomocą linii pomocniczych układu ustawić parę etykiet w widoku mapy:
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;
Ukrywanie tras alternatywnych
Gdy interfejs użytkownika jest zbyt zatłoczony, możesz ograniczyć ilość wyświetlanych informacji, wyświetlając mniej tras alternatywnych niż domyślnie (2 trasy) lub nie wyświetlając ich wcale. Możesz skonfigurować tę opcję przed pobraniem tras, konfigurując GMSNavigationRoutingOptions
i ustawiając alternateRoutesStrategy
na jedną z tych wartości:
Wartość wyliczenia | Opis |
---|---|
GMSNavigationAlternateRoutesStrategyAll | Domyślny: Wyświetla maksymalnie 2 trasy alternatywne. |
GMSNavigationAlternateRoutesStrategyOne | Wyświetla jedną trasę alternatywną (jeśli jest dostępna). |
GMSNavigationAlternateRoutesStrategyNone | Ukrywa trasy alternatywne. |
Przykład
Poniższy przykład kodu pokazuje, jak całkowicie ukryć alternatywne trasy.
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){...}];