탐색 UI 수정

iOS용 Navigation SDK를 사용하면 지도에 표시할 기본 UI 컨트롤 및 요소, 허용할 동작을 지정하여 지도의 사용자 환경을 수정할 수 있습니다. 탐색 UI의 시각적 모양을 수정할 수도 있습니다. 탐색 UI에 허용되는 수정사항에 관한 가이드라인은 정책 페이지를 참고하세요.

지도 UI 컨트롤

Navigation SDK는 iOS용 Google 지도 애플리케이션에 있는 것과 유사한 UI 컨트롤을 기본으로 제공합니다. GMSUISettings 클래스를 사용하여 이러한 컨트롤의 공개 상태를 전환할 수 있습니다. 이 클래스의 변경사항은 지도에 즉시 반영됩니다.

나침반

Navigation SDK는 특정 상황에서 그리고 사용 설정된 경우에만 지도의 오른쪽 상단에 표시되는 나침반 그래픽을 제공합니다. 나침반은 카메라의 방향이 정북이 아닌 방위 (0이 아닌 방위)를 갖는 경우에만 표시됩니다. 사용자가 나침반을 클릭하면 방위가 0인 위치 (기본 방향)로 카메라가 다시 움직이고 나침반은 곧 사라집니다.

내비게이션이 사용 설정되어 있고 카메라 모드가 '따라가기'로 설정된 경우 나침반이 계속 표시되고 나침반을 탭하면 기울어진 카메라 시점과 전체 카메라 시점 간에 전환됩니다.

나침반은 기본적으로 비활성화되어 있습니다. 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로 설정합니다. 중심 재설정 버튼이 표시되지 않도록 하려면 recenterButtonEnabledNO로 설정합니다.

Swift

mapView.settings.isRecenterButtonEnabled = true

Objective-C

mapView.settings.recenterButtonEnabled = YES;

지도 UI 액세서리

Navigation SDK는 iOS용 Google 지도 애플리케이션에 표시되는 것과 유사한 내비게이션 중에 표시되는 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:)가 하나 있습니다. 지정된 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. 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가 지도 하단에 속도 제한 컨트롤을 표시하여 현재 속도 제한을 표시합니다. 운전자가 속도 제한을 초과하면 컨트롤이 확장되어 운전자의 현재 속도가 포함된 두 번째 속도계를 표시합니다.

알림 수준을 설정하여 운전자가 지정된 시간만큼 속도 제한을 초과할 때 속도계 디스플레이의 형식을 변경할 수 있습니다. 예를 들어 운전자가 속도 제한을 5mph 초과할 때는 현재 속도가 빨간색 텍스트 색상으로 표시되고, 운전자가 속도 제한을 10mph 초과할 때는 빨간색 배경색으로 표시되도록 지정할 수 있습니다.

속도 제한 제어를 표시하려면 GMSUISettingsshouldDisplaySpeedometer 속성을 YES로 설정합니다. 속도 제한 제어의 표시를 중지하려면 shouldDisplaySpeedometerNO로 설정합니다.

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 - 확대/축소 동작의 사용 설정 또는 사용 중지 여부를 제어합니다. 사용 설정하면 사용자가 두 번 탭하거나 두 손가락으로 탭하거나 손가락을 모아서 카메라를 확대/축소할 수 있습니다. 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를 설정하여 이 옵션을 구성할 수 있습니다.

열거형 값설명
GMSNavigationAlternateRoutesStrategyAll 클래스의 생성자 기본값입니다. 최대 2개의 대체 경로를 표시합니다.
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){...}];