ナビゲーション UI を変更する

Navigation SDK for iOS を使用すると、地図に表示する組み込みの UI コントロールと要素、許可する操作を指定して、地図のユーザー エクスペリエンスを変更できます。ナビゲーション UI の外観を変更することもできます。ナビゲーション UI で許可される変更に関するガイドラインについては、ポリシー ページをご覧ください。

地図の UI コントロール

Navigation SDK には、Google Maps for iOS アプリケーションのものに似た、組み込み UI コントロールがあります。これらのコントロールの表示と非表示を切り替えるには、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 に設定します。再中央揃えボタンが表示されないようにするには、recenterButtonEnabledfalse に設定します。

Swift

mapView.settings.isRecenterButtonEnabled = true

Objective-C

mapView.settings.recenterButtonEnabled = YES;

地図 UI アクセサリ

Navigation SDK には、ナビゲーション中に表示される、Google Maps for iOS アプリケーションのものに似た UI アクセサリが用意されています。これらのコントロールの表示または外観は、このセクションで説明するように調整できます。ここで行った変更は、ユーザーの次のルートに反映されます。

ナビゲーション中は、ナビゲーション ヘッダーが画面上部に、ナビゲーション フッターが画面下部に表示されます。ナビゲーション ヘッダーには、ルートの次の曲がり角の道路名と方向、および次の曲がり角の方向が表示されます。ナビゲーションのフッターには、目的地までの推定所要時間と距離、および到着予定時刻が表示されます。

次のプロパティを使用して、ナビゲーション ヘッダーとフッターの表示を切り替え、色をプログラムで設定できます。

  • 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: という必須メソッドが 1 つあります。指定された mapView でビューに使用できる最大サイズが指定され、ビューに必要な高さを指定する必要があります。

次に、setHeaderAccessoryView: を呼び出してこのビューを mapView に渡します。mapView は現在のビューをアニメーションで非表示にし、カスタムビューをアニメーションで表示します。カスタム ビューを表示するには、ナビゲーション ヘッダーを表示する必要があります。

カスタム ヘッダー アクセサリ ビューを削除するには、nilsetHeaderAccessoryView: に渡します。

ビューのサイズをいつでも変更する必要がある場合は、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 つを示しています。これらの手順は、実装内容によって異なる場合があります。

  1. GMSNavigator(ナビゲーター)の setDestinations が正常に完了し、ナビゲーターの guidanceActive が有効になったら、エントリ ポイント ボタンを有効にします。
  2. ユーザーがエントリ ポイント ボタンをタップすると、GMSMapViewmapView)に関連付けられたナビゲータを使用して GMSNavigationDirectionsListController(コントローラ)を作成します。
  3. コントローラを UIViewController(ビュー コントローラ)のインスタンスに追加し、directionsListView をビュー コントローラのサブビューとして追加します。コントローラ上の reloadData メソッドと invalidateLayout メソッドは、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];
  ...
}

...

ルートの進行状況バー

ナビゲーションに追加されたルートの進行状況バー。

ルートの進行状況バーは、ナビを開始すると地図の右端に縦方向に表示されるバーです。有効にすると、ルート全体の概要と、ユーザーの目的地と現在地が表示されます。

これにより、ユーザーはズームインしなくても、交通などの今後の問題をすばやく予測できます。必要に応じてルートを変更できます。ユーザーがルートを変更すると、その地点から新しいルートとして開始されたかのように、進行状況バーがリセットされます。

ルートの進行状況バーには、次のステータス インジケーターが表示されます。

  • 交通状況 - 今後の交通状況。

  • 現在地 - ドライバーの現在の位置(ルート内)。

  • ルートの経過時間 - ルートの経過時間。

GMSUISettingsnavigationTripProgressBarEnabled プロパティを設定して、ルートの進行状況バーを有効にします。

Swift

mapView.settings.isNavigationTripProgressBarEnabled = true

Objective-C

mapView.settings.navigationTripProgressBarEnabled = YES;

信号機と停止標識

ナビゲーション中に表示される停止標識と信号機。

mapView で信号と停止標識を有効にできます。この機能を使用すると、ルート上の信号機や停留所のアイコンを表示できるため、より効率的で正確なルートを計画できます。

デフォルトでは、Navigation SDK for iOS では信号と停車標識は無効になっています。この機能を有効にするには、各オプション(showsTrafficLightsshowsStopSigns)の GMSMapView 設定を個別に呼び出します。


Swift

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

Objective-C

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

スピードメーター コントロール

ナビゲーションを有効にして、移動モードを運転に設定すると、iOS 版 Navigation SDK では、地図の下隅に現在の制限速度を示す制限速度コントロールが表示されます。ドライバーが速度制限を超えると、コントロールが拡大し、ドライバーの現在の速度を示す 2 つ目のスピードメーターが表示されます。

アラートレベルを設定すると、ドライバーが制限速度を指定された量超過したときに、スピードメーター表示のフォーマットを変更できます。たとえば、ドライバーが制限速度を 5 mph 超えた場合は現在の速度を赤色のテキストで表示し、10 mph 超えた場合は赤色の背景で表示するように指定できます。

速度制限コントロールを表示するには、GMSUISettingsshouldDisplaySpeedometer プロパティを true に設定します。制限速度コントロールの表示を無効にするには、shouldDisplaySpeedometerfalse に設定します。

Swift

mapView.shouldDisplaySpeedometer = true

Objective-C

mapView.shouldDisplaySpeedometer = YES;

スピードメーターのアラートの設定について詳しくは、スピードメーターのアラートを設定するをご覧ください。

デスティネーション マーカー

特定のルートの目的地マーカーの表示と非表示を切り替えるには、GMSUISettingsshowsDestinationMarkers プロパティを設定します。次の例は、目的地マーカーをオフにする方法を示しています。

Swift

mapView.settings.showsDestinationMarkers = false

Objective-C

mapView.settings.showsDestinationMarkers = NO;

地図機能

Navigation SDK を使用すると、ユーザー向けのナビゲーション エクスペリエンスをさらにカスタマイズできます。インスタンスに加えた変更は、ユーザーがアプリを次回更新するときに反映されます。

デフォルトの地図ジェスチャーを無効にする

GMSMapView のプロパティとして使用できる GMSUISettings クラスのプロパティを設定することによって、マップのデフォルトの操作を無効にすることができます。次のジェスチャーはプログラムで有効にしたり無効にしたりすることができます。操作を無効にしても、プログラムからのカメラ設定へのアクセスは制限されないことに注意してください。

  • scrollGestures - スクロール操作を有効にするか無効にするかを制御します。有効な場合、ユーザーはスワイプによってカメラをパンすることができます。
  • zoomGestures - ズーム操作を有効にするか無効にするかを制御します。有効な場合、ユーザーはダブルタップ、2 本指タップ、ピンチによってカメラをズームすることができます。scrollGestures が有効な場合にダブルタップやピンチを行うと、カメラが指定の場所にパンされる場合があることに注意してください。
  • tiltGestures - チルト操作を有効にするか無効にするかを制御します。有効な場合、ユーザーは 2 本指で上下にスワイプすることによってカメラをチルトすることができます。
  • rotateGestures - 回転操作を有効にするか無効にするかを制御します。有効な場合、ユーザーは 2 本指で回転操作を行うことによってカメラを回転することができます。

この例では、パン操作とズーム操作を無効にしています。

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 に次のいずれかの列挙値を設定して、ルートを取得する前に構成できます。

列挙値説明
GMSNavigationAlternateRoutesStrategyAll デフォルト。最大 2 つの代替ルートを表示します。
GMSNavigationAlternateRoutesStrategyOne 別のルートがある場合は、そのルートを 1 つ表示します。
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){...}];