首页 > 解决方案 > Mapbox SearchUI 未正确显示注释

问题描述

我正在构建一个测试应用程序,该应用程序在 Mapbox 的最新 RC 上运行,用于他们的地图和导航,因此必须使用最新的 SearchUI 来配合它。我遵循了我在他们的 GitHub 上找到的一些示例代码,但它似乎无法正常工作,我想知道你们中是否有人知道为什么。这是我的代码:

import UIKit
import MapboxMaps
import MapboxDirections
import MapboxCoreNavigation
import MapboxNavigation
import MapboxSearch
import MapboxSearchUI

class ViewController: UIViewController /*, MGLMapViewDelegate*/{

var navigationMapView: NavigationMapView!
var navigationViewController: NavigationViewController!
var routeOptions: NavigationRouteOptions?
var routeResponse: RouteResponse?
var startButton: UIButton!

    //SearchUI
var searchController = MapboxSearchController()
var annotationManager: PointAnnotationManager?

var mapView: MapView?


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    
    navigationMapView = NavigationMapView(frame: view.bounds)
    navigationMapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    //Sets a limit to how far the map can be zoomed out, to avoid having white borders on the top and bottom
    navigationMapView.layer.zPosition = 1
    view.addSubview(navigationMapView)
    
        // By default `NavigationViewportDataSource` tracks location changes from `PassiveLocationDataSource`, to consume
        // raw locations `ViewportDataSourceType` should be set to `.raw`.
    let navigationViewportDataSource = NavigationViewportDataSource(navigationMapView.mapView, viewportDataSourceType: .raw)
    navigationMapView.navigationCamera.viewportDataSource = navigationViewportDataSource
    
        // Allow the map to display the user's location
    navigationMapView.userLocationStyle = .puck2D()
    
        // Add a gesture recognizer to the map view
    let longPress = UILongPressGestureRecognizer(target: self, action: #selector(didLongPress(_:)))
    navigationMapView.addGestureRecognizer(longPress)
    
        // Add a button to start navigation
    displayStartButton()
    
        //SearchUI setup
    searchController.delegate = self
    let panelController = MapboxPanelController(rootViewController: searchController)
    addChild(panelController)
    //panelController.view.layer.zPosition = 2
    
    
    annotationManager = mapView?.annotations.makePointAnnotationManager()
    
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    startButton.layer.cornerRadius = startButton.bounds.midY
    startButton.clipsToBounds = true
    startButton.setNeedsDisplay()
}

func displayStartButton() {
    startButton = UIButton()
    
        // Add a title and set the button's constraints
    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.topAnchor, constant: 40).isActive = true
    startButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
    view.setNeedsLayout()
}

@objc func didLongPress(_ sender: UILongPressGestureRecognizer) {
    guard sender.state == .began else { return }
    
        // Converts point where user did a long press to map coordinates
    let point = sender.location(in: navigationMapView)
    let coordinate = navigationMapView.mapView.mapboxMap.coordinate(for: point)
    
    if let origin = navigationMapView.mapView.location.latestLocation?.coordinate {
            // Calculate the route from the user's location to the set destination
        calculateRoute(from: origin, to: coordinate)
    } else {
        print("Failed to get user location, make sure to allow location access for this application.")
    }
}

@objc func tappedButton(sender: UIButton) {
    guard let routeResponse = routeResponse, let navigationRouteOptions = routeOptions else { return }
    
    navigationViewController = NavigationViewController(for: routeResponse, routeIndex: 0,
                                                           routeOptions: navigationRouteOptions)
    navigationViewController.modalPresentationStyle = .fullScreen
    
    present(navigationViewController, animated: true, completion: nil)
}

func calculateRoute(from origin: CLLocationCoordinate2D, to destination: CLLocationCoordinate2D) {
        // Coordinate accuracy is how close the route must come to the waypoint in order to be considered viable. It is measured in meters. A negative value indicates that the route is viable regardless of how far the route is from the waypoint.
    let origin = Waypoint(coordinate: origin, coordinateAccuracy: -1, name: "Start")
    let destination = Waypoint(coordinate: destination, coordinateAccuracy: -1, name: "Finish")
     
    
        // Specify that the route is intended for automobiles avoiding traffic
    let routeOptions = NavigationRouteOptions(waypoints: [origin, destination], profileIdentifier: .automobileAvoidingTraffic)
    
        // Generate the route object and draw it on the map
    Directions.shared.calculate(routeOptions) { [weak self] (session, result) in
        switch result {
        case .failure(let error):
            print(error.localizedDescription)
        case .success(let response):
            guard let route = response.routes?.first, let strongSelf = self else {
                return
            }
            
            strongSelf.routeResponse = response
            strongSelf.routeOptions = routeOptions
            
                // Show the start button
            strongSelf.startButton?.isHidden = false
            
                // Draw the route on the map after creating it
            strongSelf.drawRoute(route: route)
            
                // Show destination waypoint on the map
            strongSelf.navigationMapView.showWaypoints(on: route)
        }
    }
}

func drawRoute(route: MapboxDirections.Route) {
    guard let routeShape = route.shape, routeShape.coordinates.count > 0 else { return }
    guard let mapView = navigationMapView.mapView else { return }
    let sourceIdentifier = "routeStyle"
    
        // Convert the route’s coordinates into a linestring feature
    let feature = Feature(geometry: .lineString(LineString(routeShape.coordinates)))
    
        // If there's already a route line on the map, update its shape to the new route
    if mapView.mapboxMap.style.sourceExists(withId: sourceIdentifier) {
        try? mapView.mapboxMap.style.updateGeoJSONSource(withId: sourceIdentifier, geoJSON: feature)
    } else {
            // Convert the route’s coordinates into a lineString Feature and add the source of the route line to the map
        var geoJSONSource = GeoJSONSource()
        geoJSONSource.data = .feature(feature)
        try? mapView.mapboxMap.style.addSource(geoJSONSource, id: sourceIdentifier)
        
            // Customize the route line color and width
        var lineLayer = LineLayer(id: "routeLayer")
        lineLayer.source = sourceIdentifier
        lineLayer.lineColor = .constant(.init(UIColor(red: 0.1897518039, green: 0.3010634184, blue: 0.7994888425, alpha: 1.0)))
        lineLayer.lineWidth = .constant(3)
        
            // Add the style layer of the route line to the map
        try? mapView.mapboxMap.style.addLayer(lineLayer)
    }
}

func showResults(_ results: [SearchResult]) {
    let annotations = results.map { searchResult -> PointAnnotation in
        var annotation = PointAnnotation(coordinate: searchResult.coordinate)
        annotation.textField = searchResult.name
        annotation.textOffset = [0, -2]
        annotation.textColor = StyleColor(.red)
        annotation.image = .default
        return annotation
    }
    
    annotationManager?.annotations = annotations
    if let point = annotations.first?.point {
        let options = CameraOptions(center: point.coordinates)
        mapView?.mapboxMap.setCamera(to: options)
    }
}
}

extension ViewController: SearchControllerDelegate {
func categorySearchResultsReceived(results: [SearchResult]) {
    showResults(results)
}

func searchResultSelected(_ searchResult: SearchResult) {
    showResults([searchResult])
}

func userFavoriteSelected(_ userFavorite: FavoriteRecord) {
    showResults([userFavorite])
}
}

某些代码与该问题无关。似乎一切正常,但是在搜索类别或地址时,注释没有显示在地图上,没有任何反应。我错过了什么吗?我让它在旧版本上工作,但很多事情都发生了变化,我没有找到任何其他文档......提前致谢!

标签: iosswiftxcodemapbox

解决方案


推荐阅读