修改導覽 UI

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

地圖 UI 控制項

Navigation SDK 提供一些內建的 UI 控制項,與 Google 地圖 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;

「Recenter」按鈕

啟用導航功能後,使用者捲動地圖檢視畫面時,最近位置按鈕就會顯示,輕觸地圖重新對齊時則會消失。如要顯示 Recenter 按鈕,請將 GMSUISettingsrecenterButtonEnabled 屬性設為 true。如要避免 recenter 按鈕顯示,請將 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];

路線清單

您可以在應用程式中提供逐步操作說明。以下範例說明其中一種可能做法。這些步驟可能會因您自己的實作方式而有所不同。

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

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

...

行程進度列

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

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

使用者不必放大,即可快速預測即將發生的問題 (例如流量)。如有需要,他們可以重新安排行程。如果使用者重新安排行程,進度列就會重設,就像從該點開始新的行程一樣。

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

  • 路況狀態:即將發生的交通狀況。

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

  • Route elapsed:行程經過的時間。

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 英里/小時時,目前車速會以紅色文字顯示,當駕駛人超速 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

列舉值說明
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){...}];