修改導覽 UI

使用 iOS 版 Navigation SDK,即可指定要在地圖上顯示哪些內建 UI 控制項和元素,以及您允許的手勢,藉此修改地圖的使用者體驗。您也可以修改 Navigation UI 的視覺外觀。請參閱政策頁面,瞭解 Navigation UI 的可接受修改方式。

地圖 UI 控制項

Navigation SDK 提供一些內建 UI 控制項,與 Google Maps iOS 版應用程式類似。您可以使用 GMSUISettings 類別切換這些控制項的顯示設定。您對這個類別所做的變更會立即反映在地圖上。

指南針

Navigation SDK 提供指南針圖形,在某些情況下 (僅限啟用時) 顯示在地圖的右上角。只有在攝影機朝向精確的北方 (非零方位) 為方向時,指南針才會顯示。使用者按一下指南針後,攝影機會移動回航向為零的位置 (預設方向),指南針隨後也會消失。

如果已啟用導覽功能,且攝影機模式設為「跟隨」,指南針會保持顯示狀態,然後輕觸傾斜和總覽相機視角之間的指南針切換鈕。

指南針預設為停用。您可以藉由將 GMSUISettingscompassButton 屬性設為 true 來啟用指南針。但無法強制指南針保持顯示。

Swift

mapView.settings.compassButton = true

Objective-C

mapView.settings.compassButton = YES;

「我的位置」按鈕

只有在啟用「我的位置」按鈕時,畫面右下角才會顯示「我的位置」按鈕。當使用者按一下按鈕時,攝影機會以動畫聚焦到使用者的目前位置 (如果目前已知使用者的位置)。如要啟用按鈕,您可以將 GMSUISettingsmyLocationButton 屬性設為 true

Swift

mapView.settings.myLocationButton = true

Objective-C

mapView.settings.myLocationButton = YES;

「重新置中」按鈕

啟用導航後,使用者捲動地圖檢視畫面時,會顯示最近按下的按鈕;使用者輕觸為地圖重新置中時,這個按鈕就會消失。如要允許顯示最近使用過的按鈕,請將 GMSUISettingsrecenterButtonEnabled 屬性設為 true。如要防止顯示最近使用過的按鈕,請將 recenterButtonEnabled 設為 false

Swift

mapView.settings.isRecenterButtonEnabled = true

Objective-C

mapView.settings.recenterButtonEnabled = YES;

地圖 UI 配件

Navigation SDK 提供在導航期間顯示的 UI 配件,類似 Google Maps for iOS 應用程式顯示的配件。您可以按照本節所述調整這些控制項的顯示設定或外觀。您在這裡所做的變更,都會反映到使用者下個行程期間。

導覽期間,導覽標頭會顯示在畫面頂端,導覽頁尾會顯示在底部。導覽標頭會顯示下次轉彎處的街道名稱和方向,以及後續轉彎的方向。導覽頁尾會顯示前往目的地的預計時間和距離,以及預計到達時間。

您可以使用下列屬性切換導覽標頭和頁尾的顯示設定,並透過程式輔助方式設定顏色:

  • navigationHeaderEnabled:控管導覽標頭是否顯示 (預設為 true)。
  • navigationFooterEnabled:控管是否顯示導覽頁尾 (預設為 true)。
  • navigationHeaderPrimaryBackgroundColor:設定導覽標頭的主要背景顏色。
  • navigationHeaderSecondaryBackgroundColor:設定導覽標頭的次要背景顏色。

以下程式碼範例說明如何開啟標頭和頁尾的顯示設定,並將 navigationHeaderPrimaryBackgroundColor 設為藍色,並將 navigationHeaderSecondaryBackgroundColor 設為紅色。

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

如要自訂應用程式,您可以將次要導覽標頭檢視畫面替換為自己的自訂配件檢視畫面。方法是建立實作 GMSNavigationAccessoryView 通訊協定的檢視表。這個通訊協定有一個必要方法:-heightForAccessoryViewConstrainedToSize:onMapView:。您已經在指定 mapView 上指定檢視區塊的可用大小上限,而必須提供檢視區塊所需的高度。

接著,您可以呼叫 setHeaderAccessoryView:,將這個檢視畫面傳遞至 mapView,方法是透過 mapView 以動畫呈現所有目前檢視畫面,然後在自訂檢視畫面中以動畫方式呈現。導覽標頭必須顯示,以便顯示自訂檢視區塊。

如要移除自訂標頭配件檢視畫面,請將 nil 傳遞至 setHeaderAccessoryView:

如果檢視區塊必須隨時變更大小,您可以呼叫 invalidateLayoutForAccessoryView:,傳入需要變更大小的檢視區塊。

範例

以下程式碼範例示範實作 GMSNavigationAccessoryView 通訊協定的自訂檢視畫面。這個自訂檢視畫面稍後會用於設定自訂導覽標頭配件檢視畫面。

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

路線清單

您可以在應用程式中提供逐步路線指引。以下示範其中一種方法。這些步驟可能會因您的實作方式而異。

  1. 成功在 GMSNavigator (導覽器) 的 setDestinations 完成後啟用進入點按鈕,且導覽器已啟用 guidanceActive
  2. 使用者輕觸進入點按鈕時,使用與 GMSMapView (mapView) 相關聯的導覽器建立 GMSNavigationDirectionsListController (控制器)。
  3. 將控制器新增至 UIViewController 的執行個體 (檢視控制器),並將 directionsListView 新增為檢視控制器的子檢視畫面。控制器上的 reloadDatainvalidateLayout 方法應像使用 UICollectionView 時呼叫的方法一樣。
  4. 將檢視控制器推送到應用程式的檢視控制器階層。

以下程式碼範例說明如何新增 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];
  ...
}

...

行程進度列

行程進度列已新增至導覽。

行程進度列是一種垂直列,會在導航開始時顯示在地圖的右側邊緣。啟用後,會顯示整趟行程的總覽,以及使用者的目的地和目前位置。

可讓使用者不必放大,就能快速預測目前發生的所有問題 (例如路況)。必要時,他們也可以重新規劃路線。如果使用者重新規劃行程,進度列會像從該點開始新行程一樣重設。

行程進度列會顯示下列狀態指標:

  • 流量狀態:近期流量的狀態。

  • 目前位置:駕駛在行程中的目前位置。

  • 路線已經過了 - 行程的經過部分。

GMSUISettings 中設定 navigationTripProgressBarEnabled 屬性,即可啟用行程進度列。

Swift

mapView.settings.isNavigationTripProgressBarEnabled = true

Objective-C

mapView.settings.navigationTripProgressBarEnabled = YES;

交通號誌和停車標誌

停止導航時顯示標誌和交通號誌。

你可以在mapView中啟用紅燈和停止標誌。這項功能可讓使用者顯示沿途交通號誌或停靠站標誌圖示,讓行程有更合適的情境,提供更有效且準確的行程。

根據預設,適用於 iOS 的 Navigation SDK 會停用交通號誌和停止標誌功能。如要啟用此功能,請分別呼叫每個選項的 GMSMapView 設定:showsTrafficLightsshowsStopSigns


Swift

mapView.settings.showsTrafficLights = true
mapView.settings.showsStopSigns = true

Objective-C

mapView.settings.showsTrafficLights = YES;
mapView.settings.showsStopSigns = YES;

計速器控制項

啟用導航且將交通模式設為行車時,iOS 版 Navigation SDK 會在地圖右下角顯示速限控制項,並顯示目前的速限。當駕駛人超出速限時,控制項會展開至第二個計速器,顯示駕駛人目前的速度。

您可以設定快訊層級,當驅動程式超出指定速限時,變更計速計顯示的格式。例如,您可以指定在驅動程式超過速限 5 mph 時,以紅色文字顏色顯示目前速度;當驅動程式超過速限時 10 英里,並以紅色背景顏色顯示。

如要顯示速限控制項,請將 GMSUISettingsshouldDisplaySpeedometer 屬性設為 true。如要停止顯示速限控制項,請將 shouldDisplaySpeedometer 設為 false

Swift

mapView.shouldDisplaySpeedometer = true

Objective-C

mapView.shouldDisplaySpeedometer = YES;

如要進一步瞭解如何設定計速計快訊,請參閱「設定計速器快訊」。

目的地標記

您可以設定 GMSUISettingsshowsDestinationMarkers 屬性,藉此顯示或隱藏特定路線的目的地標記。下例示範如何停用目的地標記。

Swift

mapView.settings.showsDestinationMarkers = false

Objective-C

mapView.settings.showsDestinationMarkers = NO;

地圖體驗功能

Navigation SDK 可讓您進一步自訂使用者的導覽體驗。您對執行個體所做的變更,會在使用者下次更新應用程式時生效。

停用預設地圖手勢

您可以設定 GMSUISettings 類別的屬性,做為 GMSMapView 的屬性,藉此停用地圖上的預設手勢。下面的手勢可以啟用和禁用編程。請注意,停用手勢不會限製程式輔助存取相機設定。

  • scrollGestures:控管是否啟用或停用捲動手勢。如果啟用,用戶可刷卡平移相機。
  • zoomGestures:控管要啟用或停用縮放手勢。如果啟用,使用者可能會輕觸兩下、雙指輕觸,或用雙指撥動縮放攝影機。請注意,在 scrollGestures 啟用的情況下,輕觸兩下或雙指撥動,可能會將攝影機平移到指定點。
  • tiltGestures:控制是否啟用或停用傾斜手勢。如果啟用,使用者將可使用雙指垂直向下或向上滑動來傾斜攝影機。
  • rotateGestures:控管是否啟用或停用旋轉手勢。如果啟用,使用者就可以使用雙指旋轉手勢旋轉相機。

在這個範例中,平移和縮放手勢都已停用。

Swift

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

Objective-C

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

位置控制項和 UI 元素

您可以使用下列屬性,根據導覽標頭和頁尾的位置放置控制項和其他 UI 元素:

  • navigationHeaderLayoutGuide
  • navigationFooterLayoutGuide

以下程式碼範例說明如何使用版面配置指南在地圖檢視畫面中放置一對標籤:

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;

隱藏替代路線

如果使用者介面過於雜亂,您可以顯示比預設路徑更少的替代路徑 (第二條),或是不顯示任何替代路徑,以減少畫面過於雜亂。您可以在擷取路徑之前設定這個選項,方法是設定 GMSNavigationRoutingOptions,並使用下列其中一個列舉值設定 alternateRoutesStrategy

列舉值說明
GMSNavigationAlternativeRoutesStrategy 全部 預設。最多可顯示兩個替代路線。
GMSNavigationAlternativeRoutesStrategyOne 顯示一個替代路線 (如果有替代路線)。
GMSNavigationAlternateRoutesStrategyNone 隱藏替代路線。

範例

以下程式碼範例示範如何完全隱藏替代路線。

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