Mengubah UI navigasi

Dengan Navigation SDK for iOS, Anda dapat mengubah pengalaman pengguna dengan peta Anda dengan menentukan kontrol UI dan elemen bawaan yang muncul di peta, serta gestur yang Anda izinkan. Anda juga dapat mengubah tampilan visual UI Navigasi. Lihat halaman Kebijakan untuk mengetahui panduan tentang modifikasi yang dapat diterima pada UI Navigasi.

Kontrol UI peta

Navigation SDK menyediakan beberapa kontrol UI bawaan yang serupa dengan yang ada di aplikasi Google Maps untuk iOS. Anda dapat mengalihkan visibilitas kontrol ini menggunakan class GMSUISettings. Perubahan yang Anda lakukan pada class ini akan segera diterapkan pada peta.

Kompas

Navigation SDK menyediakan gambar kompas yang muncul di sudut kanan atas peta dalam keadaan tertentu dan hanya jika diaktifkan. Jika pengguna mengetuk kompas, kamera akan beranimasi kembali ke posisi dengan arah nol (orientasi default), lalu kompas menghilang beberapa saat setelahnya.

Jika navigasi diaktifkan dan mode kamera disetel ke "mengikuti", kompas akan tetap terlihat dan mengetuk kompas akan beralih antara perspektif kamera miring dan ringkasan.

Untuk menghindari gangguan bagi pengemudi, kompas tetap berada di posisi yang sama jika header (dalam mode potret) meluas dan bertentangan dengan posisi default kompas. Jika Anda menambahkan kontrol kustom header sekunder atau tampilan aksesori header, kompas akan disembunyikan untuk menghindari konflik UI.

Kompas mendukung mode siang dan malam, serta mode gelap.

Kompas diaktifkan secara default di versi 11.0.0 dan yang lebih baru. Anda dapat menonaktifkan kompas dengan menyetel properti compassButton dari GMSUISettings ke false.

Swift

mapView.settings.compassButton = false

Objective-C

mapView.settings.compassButton = NO;

Tombol Lokasiku

Tombol Lokasiku akan muncul di sudut kanan bawah layar hanya jika tombol Lokasiku diaktifkan. Saat pengguna mengklik tombol tersebut, kamera akan beranimasi untuk berfokus pada lokasi pengguna saat ini jika lokasi pengguna diketahui. Anda dapat mengaktifkan tombol dengan menetapkan properti myLocationButton GMSUISettings ke true.

Swift

mapView.settings.myLocationButton = true

Objective-C

mapView.settings.myLocationButton = YES;

Tombol pusatkan lagi

Saat navigasi diaktifkan, tombol pusatkan kembali akan muncul saat pengguna men-scroll tampilan peta, dan menghilang saat pengguna mengetuk untuk memusatkan kembali peta. Untuk mengizinkan tombol pusatkan ulang muncul, tetapkan properti recenterButtonEnabled GMSUISettings ke true. Agar tombol pusatkan ulang tidak muncul, tetapkan recenterButtonEnabled ke false.

Swift

mapView.settings.isRecenterButtonEnabled = true

Objective-C

mapView.settings.recenterButtonEnabled = YES;

Aksesori UI peta

Navigation SDK menyediakan aksesori UI yang muncul selama navigasi, mirip dengan yang ada di aplikasi Google Maps untuk iOS. Anda dapat menyesuaikan visibilitas atau tampilan visual kontrol ini seperti yang dijelaskan di bagian ini. Perubahan yang Anda buat di sini akan terlihat selama perjalanan pengguna berikutnya.

Selama navigasi, header navigasi akan muncul di bagian atas layar dan footer navigasi akan muncul di bagian bawah. Header navigasi menampilkan nama jalan dan arah untuk belokan berikutnya pada rute, serta arah belokan berikutnya. Footer navigasi menampilkan perkiraan waktu dan jarak ke tujuan, serta perkiraan waktu tiba.

Anda dapat mengaktifkan/menonaktifkan visibilitas header dan footer navigasi serta menetapkan warnanya secara terprogram menggunakan properti berikut:

Contoh kode berikut menunjukkan cara mengaktifkan visibilitas untuk header dan footer, lalu menyetel navigationHeaderPrimaryBackgroundColor ke biru, dan navigationHeaderSecondaryBackgroundColor ke merah.

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];

Anda dapat menyesuaikan aplikasi dengan mengganti tampilan header navigasi sekunder dengan tampilan aksesori yang disesuaikan. Anda dapat melakukannya dengan membuat tampilan yang mengimplementasikan protokol GMSNavigationAccessoryView. Protokol ini memiliki satu metode yang diperlukan: -heightForAccessoryViewConstrainedToSize:onMapView:. Anda akan diberi ukuran maksimum yang tersedia untuk tampilan Anda di mapView tertentu, dan Anda harus memberikan tinggi yang diperlukan tampilan Anda.

Kemudian, Anda dapat meneruskan tampilan ini ke mapView dengan memanggil setHeaderAccessoryView: MapView akan menganimasikan tampilan saat ini, lalu menganimasikan tampilan kustom Anda. Header navigasi harus terlihat agar tampilan kustom Anda dapat ditampilkan.

Untuk menghapus tampilan aksesori header kustom, teruskan nil ke setHeaderAccessoryView:.

Jika tampilan Anda harus berubah ukuran kapan saja, Anda dapat memanggil invalidateLayoutForAccessoryView:, dengan meneruskan tampilan yang perlu diubah ukurannya.

Contoh

Contoh kode berikut menunjukkan tampilan kustom yang mengimplementasikan protokol GMSNavigationAccessoryView. Tampilan kustom ini kemudian digunakan untuk menetapkan tampilan aksesori header navigasi kustom.

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];

Warna header mode cahaya redup

Navigation SDK for iOS menghitung mode pencahayaan yang disarankan berdasarkan waktu dan lokasi perangkat saat ini, serta memanggil metode pemroses GMSNavigatorListener.didChangeSuggestedLightingMode saat mode yang disarankan berubah (seperti saat matahari terbit atau terbenam). Anda dapat mengubah perilaku mode low-light secara terprogram dengan cara berikut:

Daftar Rute

Anda dapat memberikan rute langkah demi langkah di aplikasi. Contoh berikut menunjukkan salah satu cara yang mungkin untuk melakukannya. Langkah-langkah ini dapat bervariasi bergantung pada penerapan Anda sendiri.

  1. Aktifkan tombol titik entri setelah setDestinations di GMSNavigator (navigator) berhasil diselesaikan dan guidanceActive di navigator telah diaktifkan.
  2. Saat pengguna mengetuk tombol titik entri, buat GMSNavigationDirectionsListController (pengontrol) dengan navigator yang terkait dengan GMSMapView (mapView).
  3. Tambahkan pengontrol ke instance UIViewController (pengontrol tampilan), dan tambahkan directionsListView sebagai subtampilan pengontrol tampilan. Metode reloadData dan invalidateLayout pada pengontrol harus dipanggil seperti yang dilakukan dengan UICollectionView.
  4. Dorong pengontrol tampilan ke hierarki pengontrol tampilan aplikasi.

Contoh kode berikut menunjukkan penambahan 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];
  ...
}

...

Status progres perjalanan

Status progres perjalanan ditambahkan ke navigasi.

Status progres perjalanan adalah status vertikal yang muncul di sisi awal/depan peta saat navigasi dimulai. Jika diaktifkan, fitur ini akan menampilkan ringkasan untuk seluruh perjalanan, beserta tujuan dan posisi pengguna saat ini.

Hal ini memungkinkan pengguna mengantisipasi masalah yang akan datang, seperti lalu lintas, tanpa perlu memperbesar. Kemudian, mereka dapat mengubah rute perjalanan jika perlu. Jika pengguna mengubah rute perjalanan, status progres akan direset seolah-olah perjalanan baru telah dimulai dari titik tersebut.

Status progres perjalanan menampilkan indikator status berikut:

  • Status traffic—status traffic mendatang.

  • Lokasi saat ini—lokasi pengemudi saat ini dalam perjalanan.

  • Route elapsed—bagian perjalanan yang telah berlalu.

Aktifkan status progres perjalanan dengan menetapkan properti navigationTripProgressBarEnabled di GMSUISettings.

Swift

mapView.settings.isNavigationTripProgressBarEnabled = true

Objective-C

mapView.settings.navigationTripProgressBarEnabled = YES;

Penempatan status progres perjalanan

  • Sisi kiri panel kira-kira sejajar dengan sisi kiri speedometer, logo Google, dan tombol Pusatkan ulang (jika terlihat). Lebarnya adalah 12 pt.
  • Status progres perjalanan merespons secara dinamis ruang vertikal di layar. Bagian bawah panel diposisikan 210 pt dari bagian bawah layar. Bagian atas status progres perjalanan tetap berjarak minimal 170 pt dari bagian atas layar, dan tinggi maksimum status adalah 400 pt.
  • Jika status progres perjalanan tumpang-tindih dengan header navigasi atau elemen UI Navigasi lainnya, status progres perjalanan akan muncul di bawah elemen lainnya tersebut.

Prompt Visibility API (Eksperimental)

Prompt Visibility API memungkinkan Anda menghindari konflik antara elemen UI yang dihasilkan oleh Navigation SDK dan elemen UI kustom Anda sendiri dengan menambahkan pemroses untuk menerima callback sebelum elemen UI Navigation SDK akan muncul dan segera setelah elemen tersebut dihapus. Untuk mengetahui informasi selengkapnya, termasuk contoh kode, lihat bagian Prompt Visibility API di halaman Mengonfigurasi gangguan real-time.

Kontrol spidometer

Jika navigasi diaktifkan dan mode perjalanan ditetapkan ke mengemudi, Navigation SDK for iOS akan menampilkan kontrol batas kecepatan di sudut bawah peta yang menunjukkan batas kecepatan saat ini. Saat pengemudi melebihi batas kecepatan, kontrol akan diperluas untuk menampilkan speedometer kedua dengan kecepatan pengemudi saat ini.

Anda dapat menetapkan tingkat peringatan untuk mengubah format tampilan speedometer saat pengemudi melebihi batas kecepatan dengan jumlah yang ditentukan. Misalnya, Anda dapat menentukan bahwa kecepatan saat ini ditampilkan dengan warna teks merah saat pengemudi melebihi batas kecepatan sebesar 5 mpj, dan dengan warna latar belakang merah saat pengemudi melebihi batas kecepatan sebesar 10 mpj.

Untuk menampilkan kontrol batas kecepatan, tetapkan properti shouldDisplaySpeedometer dari GMSUISettings ke true. Untuk menonaktifkan tampilan kontrol batas kecepatan, tetapkan shouldDisplaySpeedometer ke false.

Swift

mapView.settings.shouldDisplaySpeedometer = true

Objective-C

mapView.settings.shouldDisplaySpeedometer = YES;

Untuk mengetahui informasi selengkapnya tentang cara menyetel peringatan untuk speedometer, lihat Mengonfigurasi peringatan speedometer.

Penanda tujuan

Anda dapat menampilkan atau menyembunyikan penanda tujuan untuk rute tertentu dengan menetapkan properti showsDestinationMarkers dari GMSUISettings. Contoh berikut menunjukkan cara menonaktifkan penanda tujuan.

Swift

mapView.settings.showsDestinationMarkers = false

Objective-C

mapView.settings.showsDestinationMarkers = NO;

Fitur pengalaman peta

Navigation SDK memungkinkan Anda melakukan penyesuaian lebih lanjut pada pengalaman navigasi bagi pengguna. Perubahan yang Anda buat pada instance akan terlihat saat pengguna mengupdate aplikasi Anda berikutnya.

Penyorotan tujuan dan pintu masuk

Penyorotan tujuan dan pintu masuk

Saat tujuan dibuat dengan placeID, bangunan tujuan akan ditandai dan ikon pintu masuk akan ditampilkan jika memungkinkan. Petunjuk visual ini membantu pengguna membedakan dan membuka tujuan yang diinginkan.

Untuk membuat tujuan dengan placeID, gunakan salah satu penginisialisasi GMSNavigationWaypoint yang menerima placeID. Misalnya, tujuan yang dibuat dalam tutorial Menavigasi rute mencakup penandaan tujuan dan label pintu masuk jika tersedia.

Tampilan bangunan 3D selama navigasi

Tampilan bangunan 3D selama navigasi

Bangunan 3D ditampilkan selama navigasi secara default. Untuk menonaktifkan fitur ini, tetapkan buildingsEnabled ke false (Swift) atau NO (Objective-C).

Menonaktifkan gestur peta default

Anda dapat menonaktifkan gestur default pada peta dengan menetapkan properti class GMSUISettings, yang tersedia sebagai properti GMSMapView. Isyarat berikut bisa diaktifkan dan dinonaktifkan secara programatis. Perhatikan bahwa menonaktifkan gestur tidak akan membatasi akses terprogram ke setelan kamera.

  • scrollGestures — mengontrol apakah gestur scroll diaktifkan atau dinonaktifkan. Jika diaktifkan, pengguna dapat menggeser untuk menggerakkan kamera.
  • zoomGestures — mengontrol apakah gestur zoom diaktifkan atau dinonaktifkan. Jika diaktifkan, pengguna dapat mengetuk dua kali, mengetuk dengan dua jari, atau mencubit untuk memperbesar kamera. Perhatikan bahwa mengetuk dua kali atau mencubit saat scrollGestures diaktifkan dapat menggeser kamera ke titik yang ditentukan.
  • tiltGestures — mengontrol apakah gestur miring diaktifkan atau dinonaktifkan. Jika diaktifkan, pengguna dapat menggunakan geser vertikal ke bawah atau ke atas dengan dua jari untuk memiringkan kamera.
  • rotateGestures — mengontrol apakah gestur putar diaktifkan atau dinonaktifkan. Jika diaktifkan, pengguna dapat menggunakan gestur memutar dengan dua jari untuk memutar kamera.

Dalam contoh ini, gestur geser dan zoom telah dinonaktifkan.

Swift

mapView.settings.scrollGestures = false
mapView.settings.zoomGestures = false

Objective-C

mapView.settings.scrollGestures = NO;
mapView.settings.zoomGestures = NO;

Kontrol posisi dan elemen UI

Anda dapat memosisikan kontrol dan elemen UI lainnya sesuai dengan posisi header dan footer navigasi, menggunakan properti berikut:

  • navigationHeaderLayoutGuide
  • navigationFooterLayoutGuide
  • bottomTrailingButtonsLayoutGuide

Contoh kode berikut menunjukkan penggunaan panduan tata letak untuk memosisikan sepasang label dalam tampilan peta:

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;

Untuk contoh cara menggunakan bottomTrailingButtonsLayoutGuide, guna memosisikan tombol pelaporan gangguan real-time, lihat Mengonfigurasi gangguan real-time.

Sembunyikan rute alternatif

Jika antarmuka pengguna menjadi berantakan karena terlalu banyak informasi, Anda dapat mengurangi kekacauan dengan menampilkan lebih sedikit rute alternatif daripada default (dua), atau dengan tidak menampilkan rute alternatif sama sekali. Anda dapat mengonfigurasi opsi ini sebelum mengambil rute dengan mengonfigurasi GMSNavigationRoutingOptions, dan menetapkan alternateRoutesStrategy dengan salah satu nilai enumerasi berikut:

Nilai EnumerasiDeskripsi
GMSNavigationAlternateRoutesStrategyAll Default. Menampilkan hingga dua rute alternatif.
GMSNavigationAlternateRoutesStrategyOne Menampilkan satu rute alternatif (jika tersedia).
GMSNavigationAlternateRoutesStrategyNone Menyembunyikan rute alternatif.

Contoh

Contoh kode berikut menunjukkan cara menyembunyikan rute alternatif sepenuhnya.

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){...}];