Обновление представления карты SwiftUI Mapbox для отображения новых аннотаций к контактам при нажатии кнопки

У меня есть проект SwiftUI, в котором я хочу перенаправить геокодирование адреса в координаты и обновить представление карты Mapbox для отображения аннотации булавки в координатах этого адреса при нажатии кнопки.

При нажатии созданной мной кнопки действие, похоже, работает, но карта нигде не показывает новый вывод, хотя в мой массив аннотаций (который используется для размещения выводов) обновляется информация для нового адреса.

Мой контент и вид карты следующие:

MapView

import SwiftUI
import Mapbox



extension MGLPointAnnotation {
    convenience init(title: String, coordinate: CLLocationCoordinate2D) {
        self.init()
        self.title = title
        self.coordinate = coordinate
    }
}



    struct MapView: UIViewRepresentable {


    var mapView: MGLMapView = MGLMapView(frame: .zero, styleURL: MGLStyle.streetsStyleURL)



       @Binding var annotations: [MGLPointAnnotation]

    final class Coordinator: NSObject, MGLMapViewDelegate {
        var control: MapView

        init(_ control: MapView) {
            self.control = control
        }

        func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {

            return nil
        }


        func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
            return true
        }

    }

    func makeUIView(context: UIViewRepresentableContext<MapView>) -> MGLMapView {
        mapView.delegate = context.coordinator
        return mapView
    }


    func styleURL(_ styleURL: URL) -> MapView {
            mapView.styleURL = styleURL
            return self
        }

        func centerCoordinate(_ centerCoordinate: CLLocationCoordinate2D) -> MapView {
            mapView.centerCoordinate = centerCoordinate
            return self
        }

        func zoomLevel(_ zoomLevel: Double) -> MapView {
            mapView.zoomLevel = zoomLevel
            return self
        }

    func updateUIView(_ uiView: MGLMapView, context: UIViewRepresentableContext<MapView>) {
          updateAnnotations()
      }

      func makeCoordinator() -> MapView.Coordinator {
          Coordinator(self)
      }

      private func updateAnnotations() {
          if let currentAnnotations = mapView.annotations {
              mapView.removeAnnotations(currentAnnotations)
          }
          mapView.addAnnotations(annotations)
      }

}

ContentView

import SwiftUI
import Mapbox
import CoreLocation

struct ContentView: View {

    @ObservedObject var VModel = ViewModel()

    @ObservedObject var locationManager = LocationManager()

    var userLatitude: CLLocationDegrees {
        return (locationManager.lastLocation?.coordinate.latitude ?? 0)
     }

     var userLongitude: CLLocationDegrees {
        return (locationManager.lastLocation?.coordinate.longitude ?? 0)
     }

    var lat: Double {
        return (VModel.lat ?? 0)
    }
    var long: Double {
        return (VModel.lon ?? 0)
    }

    @State var searchedLocation: String = ""
    @State var annotations = [
        MGLPointAnnotation(title: "Mapbox", coordinate: .init(latitude: 37.791434, longitude: -122.396267))
    ]

    var body: some View {

        VStack{

            ZStack(alignment: Alignment(horizontal: .leading, vertical: .top)){

                MapView(annotations: $annotations).centerCoordinate(.init(latitude: self.lat, longitude: self.long)).zoomLevel(16).edgesIgnoringSafeArea(.all)
                VStack{
                    Button(action: {
                        self.VModel.fetchCoords(address: "address")


                        let delayInSeconds = 3.0
                        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delayInSeconds) {
                            self.annotations.append(MGLPointAnnotation(title: "Home", coordinate: .init(latitude: self.lat, longitude: self.long)))

                        }

                        print("\(self.annotations)")

                    }, label: {Text("Press to update annotation")})
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Приветствуется любая информация об обновлении карты для отображения новых аннотаций к булавкам при нажатии кнопки. Прокомментируйте, если требуется дополнительная информация


person TJ D'Alessandro    schedule 24.04.2020    source источник


Ответы (1)


Не зная о ваших от VModel до LocationManager, я вырезал их и просто жестко запрограммировал некоторые значения для некоторых аннотаций. Таким образом, хотя приведенный ниже код является значительно упрощенной версией вашего кода, вы можете увидеть добавление третьей аннотации при нажатии кнопки.

Это простая реализация, в которой модель представления (AnnotationsVM), управляющая аннотациями, обозначена как @ObservedObject в ContextView. Публикует массив аннотаций. Они передаются в переменную @Binding в MapView, и когда этот массив изменяется (добавления, удаления и т. Д.), Метод updateUIView обновляет карту.

import SwiftUI
import Mapbox

class MapViewCoordinator: NSObject, MGLMapViewDelegate {
    func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
        return true
    }
}

struct MapView: UIViewRepresentable {
    @Binding var annos: [MGLPointAnnotation]

    func makeUIView(context: Context) -> MGLMapView {
        let map = MGLMapView()
        map.styleURL = MGLStyle.outdoorsStyleURL
        map.delegate = context.coordinator

        let location = CLLocation(latitude: 40.763783, longitude: -73.973133)
        map.setCenter(location.coordinate, zoomLevel: 13, animated: true)

        return map
    }

    func updateUIView(_ uiView: MGLMapView, context: Context) {
        if let currentAnnotations = uiView.annotations {
            uiView.removeAnnotations(currentAnnotations)
        }
        uiView.addAnnotations(annos)
    }

    func makeCoordinator() -> MapViewCoordinator {
        return MapViewCoordinator()
    }
}

struct ContentView: View {
    @ObservedObject var annotationsVM = AnnotationsVM()

    var body: some View {
        NavigationView {
            MapView(annos: $annotationsVM.annos)
                .navigationBarTitle(Text("Hello"))
                .navigationBarItems(trailing: Button(action: {
                    self.annotationsVM.addNextAnnotation()
                }, label: {
                    Image(systemName: "plus.circle")
                }))
        }

    }
}

class AnnotationsVM: ObservableObject {
    @Published var annos = [MGLPointAnnotation]()

    init() {
        var annotation = MGLPointAnnotation()
        annotation.title = "Apple Store"
        annotation.coordinate = CLLocationCoordinate2D(latitude: 40.77, longitude: -73.98)
        annotation.subtitle = "Think Different"
        annos.append(annotation)

        annotation = MGLPointAnnotation()
        annotation.title = "Shoe Store"
        annotation.coordinate = CLLocationCoordinate2D(latitude: 40.78, longitude: -73.98)
        annotation.subtitle = "Shoe Different"
        annos.append(annotation)
    }

    func addNextAnnotation() {
        let newAnnotation = MGLPointAnnotation()
        newAnnotation.title = "New Annotation"
        newAnnotation.coordinate = CLLocationCoordinate2D(latitude: 40.763783, longitude: -73.973133)
        newAnnotation.subtitle = "Ben Button"
        annos.append(newAnnotation)
    }
}
person Magnas    schedule 25.04.2020