修改導覽 UI

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

地圖 UI 控制項

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

指南針

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

如果啟用導覽功能,並將相機模式設為「追蹤」,指南針就會保持可見,而且輕觸指南針會在傾斜和總覽相機視角之間切換。

指南針預設為停用。只要將 GMSUISettingscompassButton 屬性設為 YES,即可啟用指南針。但無法強制指南針保持顯示。

Swift

mapView.settings.compassButton = true

Objective-C

mapView.settings.compassButton = YES;

「我的位置」按鈕

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

Swift

mapView.settings.myLocationButton = true

Objective-C

mapView.settings.myLocationButton = YES;

「重新置中」按鈕

導航功能啟用後,使用者捲動地圖檢視時,「最近」的按鈕就會顯示,而使用者輕觸將地圖重新置中時,這個按鈕就會消失。如要允許顯示最近使用的按鈕,請將 GMSUISettingsrecenterButtonEnabled 屬性設為 YES。如果不想顯示最近使用過的按鈕,請將 recenterButtonEnabled 設為 NO

Swift

mapView.settings.isRecenterButtonEnabled = true

Objective-C

mapView.settings.recenterButtonEnabled = YES;

地圖 UI 配件

Navigation SDK 提供在導航期間顯示的 UI 配件,與 iOS 版 Google 地圖應用程式中顯示的配件類似。您可以按照本節的說明,調整這些控制項的顯示設定或視覺外觀。你在這裡所做的變更會反映在司機的下一趟行程中。

導覽期間,導覽標頭會顯示在畫面頂端,導覽頁尾會顯示在底部。導覽標頭會顯示路線中下一個轉彎處的街道名稱和方向,以及下列轉彎處的方向。導覽頁尾會顯示前往目的地的預估時間和距離,以及預計抵達時間。

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

  • 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 = YES;
mapView.settings.showsStopSigns = YES;

Objective-C

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

計速器控制項

啟用導航後,iOS 版 Navigation SDK 會在地圖的右下角顯示速限控制項,顯示目前的速限。當驅動程式超過速限時,控制項會展開,以顯示驅動程式目前速度的第二個計速器。

您可以設定快訊等級,在駕駛人超過指定距離時,變更計速器顯示的格式。舉例來說,您可以指定當驅動程式超過速限 5 英里時,目前速度顯示會以紅色文字顏色顯示,如果驅動程式超過速限 10 英里/小時,則將顯示紅色背景顏色。

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

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;

隱藏替代路線

當使用者介麵包含太多資訊時,您可以選擇顯示比預設 (2) 少的替代路徑,或完全不顯示替代路徑,藉此減少介面雜亂情形。您可以在擷取路徑前設定這個選項,方法是設定 GMSNavigationRoutingOptions,並使用下列其中一個列舉值設定 alternateRoutesStrategy

列舉值說明
GMSNavigationAlternativeRoutesStrategyAll 預設。最多可顯示兩條替代路線。
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){...}];