I have a SwiftUI project in which I want to forward geocode an address to coordinates and update the Mapbox map view to display a pin annotation at that address's coordinates on a button press.
When pressing the button I created, the action seems to work but the map does not show a new pin anywhere even though my annotation array (which is used for pin placement) is updated with the information for the new address.
My content and map view are as follows:
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()
}
}
Any information on updating the map to show new pin annotations on a button press is much appreciated. Please comment if more information is needed