Modyfikowanie interfejsu użytkownika

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.

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 to true).
  • navigationFooterEnabled – określa, czy stopka nawigacji jest widoczna (wartość domyślna to true).
  • 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];

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.

  1. Włącz przycisk punktu wejścia po zakończeniu działania elementu setDestinations w komponencie GMSNavigator (przewodnik) i włączeniu elementu guidanceActive w przewodniku.
  2. Gdy użytkownik kliknie przycisk punktu wejścia, utwórz GMSNavigationDirectionsListController (kontroler) z nawigatorem powiązanym z elementem GMSMapView (mapView).
  3. Dodaj kontroler do instancji UIViewController (kontroler widoku) i dodaj directionsListView jako podwidok kontrolera widoku. Metody reloadDatainvalidateLayout na kontrolerze powinny być wywoływane tak samo jak w przypadku UICollectionView.
  4. 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

Dodano pasek postępu przejazdu do nawigacji.

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;

znaki stop i sygnalizacja świetlna wyświetlane podczas nawigacji;

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 funkcja scrollGesturesjest 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ść wyliczeniaOpis
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){...}];