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 đồ bằng cách xác định những thành phần và chế độ điều khiển giao diện người dùng tích hợp nào xuất hiện trên bản đồ, cũng như những cử chỉ mà bạn cho phép. Bạn cũng có thể sửa đổi giao diện 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 các 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 thành phần điều khiển trên giao diện người dùng của bản đồ

Navigation SDK cung cấp một số thành phần điều khiển giao diện người dùng tích hợp sẵn tương tự như các thành phần điều khiển 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 trên lớp này sẽ được phản ánh ngay lập tức trên bản đồ.

La bàn

SDK Điều hướng cung cấp một biểu đồ la bàn xuất hiện ở góc trên cùng bên phải của bản đồ trong một số trường hợp nhất định 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ó góc phương vị khác với chính bắc (góc phương vị khác 0). Khi người dùng nhấp vào la bàn, máy ảnh sẽ tạo ảnh động quay lại vị trí có góc phương vị bằng 0 (hướng mặc định) và la bàn sẽ biến mất ngay sau đó.

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

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 true. 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 chỉ xuất hiện ở góc dưới cùng bên phải màn hình khi bạn bật nút Vị trí của tôi. Khi người dùng nhấp vào nút này, camera sẽ tạo ảnh động để lấy nét 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 đã được xác định. 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 true.

Swift

mapView.settings.myLocationButton = true

Objective-C

mapView.settings.myLocationButton = YES;

Nút Căn giữa

Khi bạn bật tính năng điều hướng, nút recenter (đặt lại tâm) 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 để đặt lại tâm bản đồ. Để cho phép nút gần đây nhất xuất hiện, hãy đặt thuộc tính recenterButtonEnabled của GMSUISettings thành true. Để ngăn nút gần đây xuất hiện, hãy đặt recenterButtonEnabled thành false.

Swift

mapView.settings.isRecenterButtonEnabled = true

Objective-C

mapView.settings.recenterButtonEnabled = YES;

Phụ kiện giao diện người dùng của Maps

Navigation SDK cung cấp các phụ kiện giao diện người dùng xuất hiện trong quá trình đ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 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ẽ được áp dụng trong chuyến đi tiếp theo của người dùng.

Trong quá trình điều hướng, tiêu đề điều hướng sẽ xuất hiện ở đầu màn hình và chân trang điều hướng sẽ xuất hiện ở cuối. Tiêu đề điều hướng cho biết tên đường và hướng rẽ tiếp theo trên tuyến đường, cũng như hướng rẽ tiếp theo. Chân trang điều hướng cho biết thời gian và quãng đường ước tính đến đích, 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 cho các thành phần này theo phương thức lập trình bằng cách sử dụng các thuộc tính sau:

  • navigationHeaderEnabled – kiểm soát việc tiêu đề điều hướng có hiển thị hay không (mặc định là true).
  • navigationFooterEnabled – kiểm soát việc chân trang điều hướng có hiển thị 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.

Ví dụ về mã sau đây cho thấy cách 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ế thành phần hiển thị tiêu đề điều hướng phụ bằng thành phần hiển thị phụ kiện tuỳ chỉnh của riêng bạn. Bạn thực hiện việc này bằng cách tạo một thành phần 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 thành phần hiển thị trên mapView đã cho và bạn phải cung cấp chiều cao mà thành phần hiển thị yêu cầu.

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

Để xoá thành phần hiển thị phụ tiêu đề tuỳ chỉnh, hãy truyền nil đến setHeaderAccessoryView:.

Nếu thành phần 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 thành phần hiển thị cần thay đổi kích thước.

Ví dụ:

Ví dụ về mã sau đây minh hoạ một thành phần hiển thị tuỳ chỉnh triển khai giao thức GMSNavigationAccessoryView. Sau đó, thành phần hiển thị tuỳ chỉnh này được dùng để đặt thành phần hiển thị phụ 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 đường đi

Bạn có thể cung cấp hướng dẫn từng bước trong ứng dụng. Ví dụ sau đây cho thấy một cách có thể 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 triển khai của riêng bạn.

  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 liên kết với GMSMapView (mapView).
  3. Thêm trình điều khiển vào một thực thể của UIViewController (trình điều khiển thành phần hiển thị) và thêm directionsListView làm thành phần hiển thị phụ của trình điều khiển thành phần hiển thị. Bạn nên gọi các phương thức reloadDatainvalidateLayout trên trình điều khiển như cách gọi với UICollectionView.
  4. Đẩy trình điều khiển khung hiển thị vào hệ phân cấp trình đ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 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

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

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

Tính năng này giúp người dùng nhanh chóng dự đoán mọi vấn đề sắp tới, chẳng hạn như 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 dùng định tuyến lại chuyến đi, thanh tiến trình sẽ đặt lại như thể một 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:

  • 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 tài xế trong chuyến đi.

  • Thời gian đã đi qua trên tuyến đường – phần thời gian đã đ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

Biển báo dừng và đèn giao thông xuất hiện trong khi đi theo chỉ dẫn.

Bạn có thể bật đèn giao thông và biển báo dừng xe trong mapView. Với tính năng này, người dùng có thể bật chế độ hiển thị đèn giao thông hoặc biểu tượng dấu dừng dọc theo tuyến đường của họ, 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 xe sẽ bị tắt trong Navigation SDK 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 = true
mapView.settings.showsStopSigns = true

Objective-C

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

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

Khi bạn bật tính năng chỉ đường và đặt chế độ đi lại thành lái xe, Navigation SDK cho iOS sẽ hiển thị một nút điều khiển giới hạn tốc độ ở góc dưới của bản đồ, cho biết 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ị một đồng hồ tốc độ thứ hai với tốc độ hiện tại của người lái xe.

Bạn có thể đặt các cấp độ 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 độ theo một lượng đã chỉ định. Ví dụ: bạn có thể chỉ định tốc độ hiện tại hiển thị bằng màu văn bản đỏ khi người lái xe vượt quá giới hạn tốc độ 5 dặm/giờ và bằng 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ị chế độ điều khiển giới hạn tốc độ, hãy đặt thuộc tính shouldDisplaySpeedometer của GMSUISettings thành true. Để tắt chế độ hiển thị kiểm soát giới hạn tốc độ, hãy đặt shouldDisplaySpeedometer thành false.

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 đồng hồ tốc độ.

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

Bạn có thể hiện hoặc ẩn điểm đánh dấu đích đế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 điểm đánh dấu đích.

Swift

mapView.settings.showsDestinationMarkers = false

Objective-C

mapView.settings.showsDestinationMarkers = NO;

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

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

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

Bạn có thể tắt các cử chỉ mặc định trên bản đồ bằng cách đặt thuộc tính của lớp GMSUISettings. Lớp này 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. Xin 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 chế độ cài đặt máy ảnh.

  • scrollGestures – kiểm soát việc có bật hay tắt cử chỉ cuộn hay không. Nếu được bật, người dùng có thể vuốt để xoay máy ảnh.
  • zoomGestures – kiểm soát việc có bật hay tắt cử chỉ thu phóng hay không. Nếu được bật, người dùng có thể nhấn đúp, nhấn bằng hai ngón tay hoặc chụm để thu phóng máy ảnh. Xin lưu ý rằng thao tác nhấn đúp hoặc chụm khi bật scrollGestures 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ể dùng hai ngón tay vuốt lên hoặc xuống theo chiều dọc để nghiêng máy ảnh.
  • rotateGestures – kiểm soát việc có bật cử chỉ xoay hay không. Nếu được bật, người dùng có thể sử dụng cử chỉ xoay 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;

Các thành phần điều khiển vị trí và 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 thành phần khác trên giao diện người dùng so với vị trí của tiêu đề 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 các nguyên tắc bố cục để định vị 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 do có quá nhiều thông tin, bạn có thể giảm tình trạng lộn xộn bằng cách hiển thị ít tuyến đường thay thế hơn so với mặc định (2) hoặc không hiển thị tuyến đường thay thế nào cả. 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êMô tả
GMSNavigationAlternateRoutesStrategyAll Mặc định. Hiển thị tối đa 2 tuyến đường thay thế.
GMSNavigationAlternateRoutesStrategyOne Hiển thị một tuyến đường 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 đường 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){...}];