Sửa đổi giao diện người dùng điều hướng

Khi sử dụng SDK Điều hướng cho iOS, bạn có thể sửa đổi trải nghiệm người dùng với bản đồ của mình bằng cách xác định những thành phần và thành phần điều khiển trên giao diện người dùng tích hợp sẵn sẽ xuất hiện trên bản đồ, cũng như những cử chỉ bạn cho phép. Bạn cũng có thể sửa đổi giao diện trực quan của Giao diện người dùng Điều hướng. Hãy tham khảo trang Chính sách để biết nguyên tắc về những nội dung sửa đổi được chấp nhận đối với Giao diện người dùng điều hướng.

Các chế độ điều khiển trên giao diện người dùng của bản đồ

SDK Điều hướng cung cấp một số chế độ điều khiển trên giao diện người dùng tích hợp sẵn, tương tự như các chế độ điều khiển có trong ứng dụng Google Maps dành cho iOS. Bạn có thể bật/tắt chế độ hiển thị của các chế độ điều khiển này bằng cách sử dụng lớp GMSUISettings. Những thay đổi bạn thực hiện đối với lớp này sẽ phản ánh ngay lập tức trên bản đồ.

La bàn

SDK Điều hướng cung cấp đồ hoạ la bàn xuất hiện ở góc trên cùng bên phải bản đồ trong một số trường hợp và chỉ khi được bật. La bàn chỉ xuất hiện khi máy ảnh được định hướng sao cho có một vòng bi khác với góc chính xác hướng bắc (một góc phương vị khác 0). Khi người dùng nhấp vào la bàn, máy ảnh sẽ chuyển động trở lại vị trí có phương hướng bằng 0 (hướng mặc định) và la bàn biến mất ngay sau đó.

Nếu bạn bật tính năng chỉ đường và chế độ máy ảnh được đặt thành "theo dõi", thì la bàn sẽ vẫn hiển thị và bạn nhấn vào nút bật/tắt la bàn giữa góc nhìn của máy ảnh nghiêng và góc nhìn tổng quan.

Theo mặc định, la bàn bị tắt. Bạn có thể bật la bàn bằng cách đặt thuộc tính compassButton của GMSUISettings thành YES. Tuy nhiên, bạn không thể buộc la bàn luôn hiển thị.

Swift

mapView.settings.compassButton = true

Objective-C

mapView.settings.compassButton = YES;

Nút Vị trí của tôi

Nút Vị trí của tôi xuất hiện ở góc dưới bên phải màn hình chỉ khi nút Vị trí của tôi được bật. Khi người dùng nhấp vào nút đó, máy ảnh sẽ tạo ảnh động để tập trung vào vị trí hiện tại của người dùng nếu vị trí của người dùng hiện đã biết. Bạn có thể bật nút này bằng cách đặt thuộc tính myLocationButton của GMSUISettings thành YES.

Swift

mapView.settings.myLocationButton = true

Objective-C

mapView.settings.myLocationButton = YES;

Nút căn giữa

Khi bật tính năng chỉ đường, nút căn giữa sẽ xuất hiện khi người dùng cuộn chế độ xem bản đồ và biến mất khi người dùng nhấn để căn giữa lại bản đồ. Để cho phép nút căn giữa xuất hiện, hãy đặt thuộc tính recenterButtonEnabled của GMSUISettings thành YES. Để ngăn nút căn giữa xuất hiện, hãy đặt recenterButtonEnabled thành NO.

Swift

mapView.settings.isRecenterButtonEnabled = true

Objective-C

mapView.settings.recenterButtonEnabled = YES;

Phụ kiện giao diện người dùng của bản đồ

SDK điều hướng cung cấp các phụ kiện giao diện người dùng xuất hiện trong khi điều hướng tương tự như các phụ kiện trong ứng dụng Google Maps dành cho iOS. Bạn có thể điều chỉnh chế độ hiển thị hoặc giao diện trực quan của các chế độ điều khiển này như mô tả trong phần này. Những thay đổi bạn thực hiện ở đây sẽ phản ánh trong chuyến đi tiếp theo của người lái xe.

Trong khi điều hướng, tiêu đề điều hướng xuất hiện ở đầu màn hình còn chân trang điều hướng xuất hiện ở dưới cùng. Tiêu đề điều hướng cho biết tên đường phố và hướng của ngã rẽ tiếp theo trên tuyến đường, cũng như hướng của ngã rẽ tiếp theo. Chân trang điều hướng cho biết thời gian dự kiến và khoảng cách tới điểm đến, cũng như thời gian đến dự kiến.

Bạn có thể bật/tắt chế độ hiển thị của tiêu đề và chân trang điều hướng, cũng như đặt màu sắc theo phương thức lập trình bằng các thuộc tính sau:

  • navigationHeaderEnabled – kiểm soát việc có hiển thị tiêu đề điều hướng hay không (mặc định là true).
  • navigationFooterEnabled – kiểm soát việc có hiển thị chân trang điều hướng hay không (mặc định là true).
  • navigationHeaderPrimaryBackgroundColor – đặt màu nền chính cho tiêu đề điều hướng.
  • navigationHeaderSecondaryBackgroundColor – đặt màu nền phụ cho tiêu đề điều hướng.

Mã ví dụ sau đây cho thấy việc bật chế độ hiển thị cho tiêu đề và chân trang, sau đó đặt navigationHeaderPrimaryBackgroundColor thành màu xanh dương và navigationHeaderSecondaryBackgroundColor thành màu đỏ.

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];

Bạn có thể tuỳ chỉnh ứng dụng bằng cách thay thế chế độ xem tiêu đề điều hướng phụ bằng chế độ xem phụ kiện tuỳ chỉnh của riêng mình. Bạn thực hiện việc này bằng cách tạo một khung hiển thị triển khai giao thức GMSNavigationAccessoryView. Giao thức này có một phương thức bắt buộc: -heightForAccessoryViewConstrainedToSize:onMapView:. Bạn được cung cấp kích thước tối đa có sẵn cho khung hiển thị của mình trên mapView đã cho và bạn phải cung cấp chiều cao mà khung hiển thị yêu cầu.

Sau đó, bạn có thể chuyển khung hiển thị này đến mapView bằng cách gọi setHeaderAccessoryView:. MapView sẽ tạo ảnh động cho mọi khung hiển thị hiện tại, sau đó tạo ảnh động trong khung hiển thị tuỳ chỉnh. Bạn phải nhìn thấy tiêu đề điều hướng để khung hiển thị tuỳ chỉnh có thể xuất hiện.

Để xoá chế độ xem tiêu đề phụ kiện tuỳ chỉnh, hãy truyền nil đến setHeaderAccessoryView:

Nếu khung hiển thị của bạn phải thay đổi kích thước bất cứ lúc nào, thì bạn có thể gọi invalidateLayoutForAccessoryView:, truyền vào khung hiển thị cần thay đổi kích thước.

Ví dụ:

Ví dụ về mã sau đây minh hoạ một khung hiển thị tuỳ chỉnh giúp triển khai giao thức GMSNavigationAccessoryView. Sau đó, khung hiển thị tuỳ chỉnh này sẽ được dùng để đặt khung hiển thị phụ kiện cho tiêu đề điều hướng tuỳ chỉnh.

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];

Danh sách chỉ đường

Bạn có thể cung cấp thông tin hướng dẫn từng bước trong ứng dụng của mình. Ví dụ sau đây cho thấy một cách khả thi để thực hiện việc này. Các bước này có thể khác nhau tuỳ thuộc vào cách bạn triển khai.

  1. Bật nút điểm truy cập sau khi setDestinations trên GMSNavigator (trình điều hướng) đã hoàn tất thành công và guidanceActive trên trình điều hướng đã được bật.
  2. Khi người dùng nhấn vào nút điểm truy cập, hãy tạo một GMSNavigationDirectionsListController (bộ điều khiển) với trình điều hướng được liên kết với GMSMapView (mapView).
  3. Thêm bộ điều khiển vào thực thể của UIViewController (bộ điều khiển khung hiển thị) và thêm directionsListView làm khung hiển thị phụ của bộ điều khiển khung hiển thị. Các phương thức reloadDatainvalidateLayout trên trình điều khiển phải được gọi như với UICollectionView.
  4. Đẩy bộ điều khiển chế độ xem vào hệ phân cấp bộ điều khiển khung hiển thị của ứng dụng.

Ví dụ về mã sau đây cho thấy cách thêm một 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];
  ...
}

...

Thanh tiến trình chuyến đi

Đã thêm thanh tiến trình chuyến đi vào phần điều hướng.

Thanh tiến trình chuyến đi là một thanh dọc xuất hiện ở cạnh bên phải của bản đồ khi tính năng chỉ đường bắt đầu. Khi được bật, xe sẽ hiển thị thông tin tổng quan cho toàn bộ chuyến đi, cùng với điểm đến và vị trí hiện tại của người lái xe.

API này mang lại cho người lái xe khả năng dự đoán nhanh mọi vấn đề sắp tới (chẳng hạn như vấn đề về lưu lượng truy cập) mà không cần phóng to. Sau đó, họ có thể định tuyến lại chuyến đi nếu cần. Nếu người lái xe định tuyến lại chuyến đi, thanh tiến trình sẽ đặt lại như thể chuyến đi mới đã bắt đầu từ thời điểm đó.

Thanh tiến trình chuyến đi hiển thị các chỉ báo trạng thái sau đây:

  • Trạng thái lưu lượng truy cập: trạng thái của lưu lượng truy cập sắp tới.

  • Vị trí hiện tại – vị trí hiện tại của người lái xe trong chuyến đi.

  • Tuyến đường đã trôi qua — phần đã trôi qua của chuyến đi.

Bật thanh tiến trình chuyến đi bằng cách đặt thuộc tính navigationTripProgressBarEnabled trong GMSUISettings.

Swift

mapView.settings.isNavigationTripProgressBarEnabled = true

Objective-C

mapView.settings.navigationTripProgressBarEnabled = YES;

Đèn giao thông và biển báo dừng

Dừng các biển báo và đèn giao thông hiển thị trong khi đi theo chỉ dẫn.

Bạn có thể bật đèn giao thông và biển báo dừng trong mapView. Với tính năng này, người lái xe có thể bật chế độ hiển thị đèn giao thông hoặc biểu tượng biển báo dừng dọc theo tuyến đường, cung cấp bối cảnh tốt hơn cho các chuyến đi hiệu quả và chính xác hơn.

Theo mặc định, đèn giao thông và biển báo dừng bị tắt trong SDK điều hướng dành cho iOS. Để bật tính năng này, hãy gọi chế độ cài đặt GMSMapView cho từng tuỳ chọn một cách độc lập: showsTrafficLightsshowsStopSigns.


Swift

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

Objective-C

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

Điều khiển đồng hồ tốc độ

Khi tính năng chỉ đường được bật, SDK Điều hướng cho iOS sẽ hiển thị giới hạn tốc độ ở góc dưới của bản đồ cho thấy giới hạn tốc độ hiện tại. Khi người lái xe vượt quá giới hạn tốc độ, chế độ điều khiển sẽ mở rộng để hiển thị đồng hồ tốc độ thứ hai với tốc độ hiện tại của người lái.

Bạn có thể đặt các mức cảnh báo để thay đổi định dạng của màn hình đồng hồ tốc độ khi người lái xe vượt quá giới hạn tốc độ một mức đã chỉ định. Ví dụ: bạn có thể chỉ định rằng tốc độ hiện tại sẽ có màu văn bản màu đỏ khi người lái xe vượt quá giới hạn tốc độ 5 dặm/giờ và với màu nền đỏ khi người lái xe vượt quá giới hạn tốc độ 10 dặm/giờ.

Để hiển thị bảng điều khiển giới hạn tốc độ, hãy đặt thuộc tính shouldDisplaySpeedometer của GMSUISettings thành YES. Để tắt chế độ hiển thị bộ điều khiển giới hạn tốc độ, hãy đặt shouldDisplaySpeedometer thành NO.

Swift

mapView.shouldDisplaySpeedometer = true

Objective-C

mapView.shouldDisplaySpeedometer = YES;

Để biết thêm thông tin về cách đặt cảnh báo cho đồng hồ tốc độ, hãy xem phần Định cấu hình cảnh báo trên đồng hồ tốc độ.

Điểm đánh dấu điểm đến

Bạn có thể hiện hoặc ẩn điểm đánh dấu điểm đến cho một tuyến đường nhất định bằng cách đặt thuộc tính showsDestinationMarkers của GMSUISettings. Ví dụ sau đây cho thấy cách tắt các điểm đánh dấu điểm đến.

Swift

mapView.settings.showsDestinationMarkers = false

Objective-C

mapView.settings.showsDestinationMarkers = NO;

Các tính năng của trải nghiệm bản đồ

SDK Điều hướng cho phép bạn tuỳ chỉnh hơn nữa trải nghiệm chỉ đường cho người dùng. Những thay đổi bạn thực hiện cho thực thể sẽ được phản ánh trong lần cập nhật ứng dụng tiếp theo của trình điều khiển.

Tắt các cử chỉ bản đồ mặc định

Bạn có thể tắt các cử chỉ mặc định trên bản đồ bằng cách đặt các thuộc tính của lớp GMSUISettings (có sẵn dưới dạng thuộc tính của GMSMapView). Bạn có thể bật và tắt các cử chỉ sau theo phương thức lập trình. Lưu ý rằng việc tắt cử chỉ sẽ không giới hạn quyền truy cập có lập trình vào các chế độ cài đặt máy ảnh.

  • scrollGestures – kiểm soát việc bật hay tắt các cử chỉ cuộn. Nếu chế độ này được bật, người dùng có thể vuốt để lia máy ảnh.
  • zoomGestures – kiểm soát việc bật hay tắt các cử chỉ thu phóng. Nếu được bật, người dùng có thể nhấn đúp, nhấn bằng 2 ngón tay hoặc chụm để thu phóng máy ảnh. Lưu ý rằng thao tác nhấn đúp hoặc chụm khi scrollGestures đang bật có thể xoay máy ảnh đến điểm đã chỉ định.
  • tiltGestures – kiểm soát việc bật hay tắt cử chỉ nghiêng. Nếu được bật, người dùng có thể sử dụng thao tác vuốt xuống hoặc vuốt lên bằng hai ngón tay để nghiêng máy ảnh.
  • rotateGestures – kiểm soát việc bật hay tắt các cử chỉ xoay. Nếu được bật, người dùng có thể sử dụng cử chỉ xoay bằng hai ngón tay để xoay máy ảnh.

Trong ví dụ này, cả cử chỉ kéo và thu phóng đều đã bị tắt.

Swift

mapView.settings.scrollGestures = false
mapView.settings.zoomGestures = false

Objective-C

mapView.settings.scrollGestures = NO;
mapView.settings.zoomGestures = NO;

Thành phần điều khiển vị trí và thành phần trên giao diện người dùng

Bạn có thể định vị các thành phần điều khiển và các phần tử khác trên giao diện người dùng theo vị trí của đầu trang và chân trang điều hướng bằng cách sử dụng các thuộc tính sau:

  • navigationHeaderLayoutGuide
  • navigationFooterLayoutGuide

Ví dụ về mã sau đây cho thấy cách sử dụng hướng dẫn bố cục để đặt một cặp nhãn trong chế độ xem bản đồ:

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;

Ẩn các tuyến đường thay thế

Khi giao diện người dùng trở nên lộn xộn với quá nhiều thông tin, bạn có thể giảm sự lộn xộn bằng cách cho thấy ít tuyến thay thế hơn so với mặc định (hai) hoặc bằng cách không hiển thị tuyến đường thay thế nào. Bạn có thể định cấu hình tuỳ chọn này trước khi tìm nạp các tuyến bằng cách định cấu hình GMSNavigationRoutingOptions và đặt alternateRoutesStrategy bằng một trong các giá trị liệt kê sau:

Giá trị liệt kêNội dung mô tả
GMSNavigationChangeRoutesStrategyAll Mặc định. Hiển thị tối đa hai tuyến thay thế.
GMSNavigationthayRoutesStrategyOne Hiển thị một tuyến thay thế (nếu có).
GMSNavigationAlternateRoutesStrategyNone Ẩn các tuyến đường thay thế.

Ví dụ:

Ví dụ về mã sau đây minh hoạ cách ẩn hoàn toàn các tuyến thay thế.

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){...}];