Beta
Navigation SDK for iOS v2

Advanced navigation app

AdvancedViewController
import UIKit
import MapboxCoreNavigation
import MapboxNavigation
import MapboxDirections
import MapboxMaps
class AdvancedViewController: UIViewController, NavigationMapViewDelegate, NavigationViewControllerDelegate {
var navigationMapView: NavigationMapView!
var navigationRouteOptions: NavigationRouteOptions!
var currentRoute: Route? {
get {
return routes?.first
}
set {
guard let selected = newValue else { routes?.remove(at: 0); return }
guard let routes = routes else { self.routes = [selected]; return }
self.routes = [selected] + routes.filter { $0 != selected }
}
}
var routes: [Route]? {
didSet {
guard let routes = routes, let current = routes.first else {
navigationMapView.removeRoutes()
return
}
navigationMapView.show(routes)
navigationMapView.showWaypoints(on: current)
}
}
var startButton: UIButton!
// MARK: - UIViewController lifecycle methods
override func viewDidLoad() {
super.viewDidLoad()
navigationMapView = NavigationMapView(frame: view.bounds)
navigationMapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
navigationMapView.delegate = self
navigationMapView.userLocationStyle = .puck2D()
let navigationViewportDataSource = NavigationViewportDataSource(navigationMapView.mapView, viewportDataSourceType: .raw)
navigationViewportDataSource.options.followingCameraOptions.zoomUpdatesAllowed = false
navigationViewportDataSource.followingMobileCamera.zoom = 13.0
navigationMapView.navigationCamera.viewportDataSource = navigationViewportDataSource
let gesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
navigationMapView.addGestureRecognizer(gesture)
view.addSubview(navigationMapView)
startButton = UIButton()
startButton.setTitle("Start Navigation", for: .normal)
startButton.translatesAutoresizingMaskIntoConstraints = false
startButton.backgroundColor = .blue
startButton.contentEdgeInsets = UIEdgeInsets(top: 10, left: 20, bottom: 10, right: 20)
startButton.addTarget(self, action: #selector(tappedButton(sender:)), for: .touchUpInside)
startButton.isHidden = true
view.addSubview(startButton)
startButton.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -20).isActive = true
startButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
view.setNeedsLayout()
}
// Override layout lifecycle callback to be able to style the start button.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
startButton.layer.cornerRadius = startButton.bounds.midY
startButton.clipsToBounds = true
startButton.setNeedsDisplay()
}
@objc func tappedButton(sender: UIButton) {
guard let route = currentRoute, let navigationRouteOptions = navigationRouteOptions else { return }
// For demonstration purposes, simulate locations if the Simulate Navigation option is on.
let navigationService = MapboxNavigationService(route: route,
routeIndex: 0,
routeOptions: navigationRouteOptions,
simulating: simulationIsEnabled ? .always : .onPoorGPS)
let navigationOptions = NavigationOptions(navigationService: navigationService)
let navigationViewController = NavigationViewController(for: route, routeIndex: 0,
routeOptions: navigationRouteOptions,
navigationOptions: navigationOptions)
navigationViewController.delegate = self
present(navigationViewController, animated: true, completion: nil)
}
@objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
guard gesture.state == .ended else { return }
let location = navigationMapView.mapView.mapboxMap.coordinate(for: gesture.location(in: navigationMapView.mapView))
requestRoute(destination: location)
}
func requestRoute(destination: CLLocationCoordinate2D) {
guard let userLocation = navigationMapView.mapView.location.latestLocation else { return }
let location = CLLocation(latitude: userLocation.coordinate.latitude,
longitude: userLocation.coordinate.longitude)
let userWaypoint = Waypoint(location: location,
heading: userLocation.heading,
name: "user")
let destinationWaypoint = Waypoint(coordinate: destination)
let navigationRouteOptions = NavigationRouteOptions(waypoints: [userWaypoint, destinationWaypoint])
Directions.shared.calculate(navigationRouteOptions) { [weak self] (_, result) in
switch result {
case .failure(let error):
print(error.localizedDescription)
case .success(let response):
guard let routes = response.routes,
let currentRoute = routes.first,
let self = self else { return }
self.navigationRouteOptions = navigationRouteOptions
self.routes = routes
self.startButton?.isHidden = false
self.navigationMapView.show(routes)
self.navigationMapView.showWaypoints(on: currentRoute)
}
}
}
// Delegate method called when the user selects a route
func navigationMapView(_ mapView: NavigationMapView, didSelect route: Route) {
self.currentRoute = route
}
func navigationViewControllerDidDismiss(_ navigationViewController: NavigationViewController, byCanceling canceled: Bool) {
dismiss(animated: true, completion: nil)
}
}