繁体   English   中英

更新 SwiftUI Mapbox Map 视图以在按下按钮时显示新的引脚注释

[英]Updating a SwiftUI Mapbox Map View to Show New Pin Annotations on a Button Press

我有一个 SwiftUI 项目,我想在其中将地址地理编码转发到坐标并更新 Mapbox map 视图以在按下按钮时在该地址的坐标处显示图钉注释。

当按下我创建的按钮时,该操作似乎有效,但 map 没有在任何地方显示新的 pin,即使我的注释数组(用于 pin 放置)更新了新地址的信息。

我的内容和map查看如下:

地图视图

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)
      }

}

内容视图

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()
    }
}

非常感谢有关更新 map 以在按下按钮时显示新引脚注释的任何信息。 如果需要更多信息,请发表评论

在不知道您的VModelLocationManager的情况下,我将它们剥离出来,只是硬编码了一些注释的一些值。 因此,尽管下面的代码是您的代码的简化版本,但您可以在按下按钮时看到添加了第三个注释。

这是一个简单的实现,其中控制注释的视图模型 ( AnnotationsVM ) 在ContextView中被引用为@ObservedObject 它发布注释数组。 这些被传递到MapView中的@Binding变量,当该数组发生变化(添加、删除等)时,updateUIView 方法更新 map。

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)
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM