[英]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 以在按下按钮时显示新引脚注释的任何信息。 如果需要更多信息,请发表评论
在不知道您的VModel
到LocationManager
的情况下,我将它们剥离出来,只是硬编码了一些注释的一些值。 因此,尽管下面的代码是您的代码的简化版本,但您可以在按下按钮时看到添加了第三个注释。
这是一个简单的实现,其中控制注释的视图模型 ( 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.