修改導覽 UI

使用 Navigation SDK for iOS,您可以決定要在地圖上顯示哪些內建 UI 控制項和元素,以及允許哪些手勢,藉此修改地圖的使用者體驗。您也可以修改導航使用者介面的視覺外觀。如需導覽 UI 的可接受修改方式相關指南,請參閱「政策頁面」。

地圖 UI 控制項

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

指南針

在某些情況下,Navigation SDK 會提供指南針圖形 (顯示在地圖右上角),但僅限啟用時。使用者按一下指南針後,攝影機就會移動回航向為零的位置 (預設方向),且指南針之後很快就會消失。

如果已啟用導航功能,且攝影機模式設為「跟隨」,指南針會持續顯示,輕觸指南針即可在傾斜和鳥瞰攝影機視角之間切換。

為避免駕駛人分心,如果標題 (直向模式) 展開並與羅盤的預設位置衝突,羅盤會保持在相同位置。如果新增次要標頭自訂控制項或標頭配件檢視區塊,為避免 UI 衝突,指南針會隱藏。

指南針支援日間和夜間模式,以及深色模式。

指南針預設為停用。如要啟用指南針,請將 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 地圖 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];

夜間模式

當系統更新預估照明條件時,就會觸發 GMSNavigatorListener.didChangeSuggestedLightingMode 監聽器方法。舉例來說,當裝置目前所在位置天黑時,您可以透過下列方式,以程式輔助方式修改夜間模式行為:

路線清單

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

  1. GMSNavigator (導覽器) 上的 setDestinations 成功完成 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)
  // 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];
  ...
}

...

行程進度列

導覽畫面新增行程進度列。

導航開始時,地圖的開頭/引導側會顯示垂直的行程進度列。啟用後,系統會顯示整趟行程的總覽,以及使用者的目的地和目前位置。

使用者不必放大地圖,即可快速預測即將發生的問題,例如交通狀況。然後視需要重新規劃行程。如果使用者重新規劃路線,進度列就會重設,就像從該點開始新行程一樣。

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

  • 流量狀態:即將到來的流量狀態。

  • 目前位置:司機在行程中的目前位置。

  • 已行駛路線:行程中已行駛的路段。

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

Swift

mapView.settings.isNavigationTripProgressBarEnabled = true

Objective-C

mapView.settings.navigationTripProgressBarEnabled = YES;

行程進度列位置

  • 左側的橫條大致會與速度計、Google 標誌和「重新置中」按鈕 (顯示時) 的左側對齊。寬度為 12 點。
  • 行程進度列會根據畫面上的垂直空間動態調整。底部距離畫面底部 210 pt。行程進度列頂端與畫面頂端的距離至少為 170 pt,且進度列高度上限為 400 pt。
  • 如果行程進度列與迴轉卡或其他導航 UI 元素重疊,系統會將進度列顯示在這些元素下方。

提示瀏覽權限 API (實驗性)

您可以透過「提示顯示 API」新增監聽器,在 Navigation SDK UI 元素即將顯示前和移除後立即接收回呼,避免 Navigation SDK 產生的 UI 元素與自訂 UI 元素發生衝突。如需程式碼範例等詳細資訊,請參閱「設定即時中斷」頁面的「提示顯示 API」一節。

紅綠燈和停止標誌

導航時顯示的停車標誌和紅綠燈。

mapView 中啟用導航時,系統會顯示紅綠燈和停止標誌,提供路線和行程操作的額外背景資訊。

根據預設,Navigation SDK for iOS 會停用紅綠燈和停止標誌。如要啟用這項功能,請分別呼叫各選項的 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 英里/小時時,目前車速以紅色文字顏色顯示;當駕駛人超速 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 可讓您進一步自訂使用者的導航體驗。使用者下次更新應用程式時,系統就會套用您對執行個體所做的變更。

目的地醒目顯示和入口

醒目顯示目的地和入口。

使用 placeID 建立目的地時,系統會醒目顯示目的地建築物,並盡可能顯示入口圖示。這些視覺提示可協助使用者辨識並前往目的地。

如要使用 placeID 建立目的地,請使用接受 placeIDGMSNavigationWaypoint 初始化子。舉例來說,在導覽路線教學課程中建立的目的地會醒目顯示,並在適用的情況下顯示入口標籤。

停用預設地圖手勢

如要停用地圖上的預設手勢,請設定 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
  • bottomTrailingButtonsLayoutGuide

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

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;

如要瞭解如何使用 bottomTrailingButtonsLayoutGuide 定位即時中斷通報按鈕,請參閱「設定即時中斷」。

隱藏替代路線

如果使用者介面因資訊過多而顯得雜亂,您可以減少顯示的替代路線 (少於預設的兩條),或完全不顯示替代路線,藉此減少雜亂感。您可以在擷取路徑前設定此選項,方法是設定 GMSNavigationRoutingOptions,並將 alternateRoutesStrategy 設為下列其中一個列舉值:

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