地图注释仅在地图移动后出现



我有一个从Google API加载注释的地图,当地图最初加载所有注释时,它们被'放置',通过控制台的打印看到,但是它们不会显示在地图上,直到我移动地图一次。有人知道我是否需要调用一个方法来更新地图后放置注释?

struct ContentView: View {

var locationSearch = LocationSearch()
@State private var mapView = MapView()
@State var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: -33.7944, longitude: 151.2649), span: MKCoordinateSpan(latitudeDelta: 0.015, longitudeDelta: 0.015))
@EnvironmentObject var sheetManager: SheetManager
var body: some View {
mapView
.popup(with: SheetManager())
.frame(width: UIScreen.screenWidth, height: UIScreen.screenHeight)
}

}
struct MapView: UIViewRepresentable {
@State var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: -33.7944, longitude: 151.2649), span: MKCoordinateSpan(latitudeDelta: 0.015, longitudeDelta: 0.015))

func updateUIView(_ uiView: MKMapView, context: Context) {
print("FLF: MapView updated")
uiView.setNeedsDisplay()
}


var locationManager = CLLocationManager()
let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: UIScreen.screenWidth, height: UIScreen.screenHeight))

func setupManager() {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
}

func makeUIView(context: Context) -> MKMapView {
setupManager()
mapView.region = ContentView().region
mapView.showsUserLocation = true
mapView.userTrackingMode = .follow
mapView.delegate = context.coordinator // set the delegate to the coordinator
placeMarkersForRegion(region: region)
return mapView
}

func placeMarkersForRegion(region: MKCoordinateRegion) {
var locationSearch = LocationSearch()
locationSearch.performSearch(region: region) { venues in
print("FLF: Placing (venues.count) marker(s)")
for marker in venues {
let annotation = MKPointAnnotation()
annotation.coordinate = marker.location
annotation.title = marker.name
mapView.addAnnotation(annotation)
}
}
}

func makeCoordinator() -> MapViewCoordinator {
MapViewCoordinator(self) // pass self to the coordinator so it can call `regionDidChangeAnimated`
}
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
// Use the 'coordinate' property to get the current location of the map view
let currentRegion = mapView.region
print("FLF: Map has moved")
self.placeMarkersForRegion(region: currentRegion)
// Do something with the current region (e.g. update a state variable or perform a search)
}

}
class MapViewCoordinator: NSObject, MKMapViewDelegate {
var parent: MapView // add a property to hold a reference to the parent view
init(_ parent: MapView) {
self.parent = parent
}
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
// Call the parent's implementation of this method
parent.mapView(mapView, regionDidChangeAnimated: animated)
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
view.canShowCallout = true
view.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
// Get the tapped annotation
guard let annotation = view.annotation else { return }
// Print the title of the annotation
print(annotation.title ?? "Unknown")
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
print("FLF: Marker tapped")
}
}

UIViewRepresentableCoordinator未正确实现。例如,makeUIView必须初始化它,但您将其初始化为结构体上的属性,这将立即丢失。MapViewCoordinator(self)也是一个错误,因为self,即结构体,在SwiftUI更新后立即被忽略。

另一个问题是@State不应该持有一个视图,就像你的ContentView@StateMapView

下面是如何使用MKMapViewUIViewRepresentable的例子:

struct MKMapViewRepresentable: UIViewRepresentable {
@Binding var userTrackingMode: MapUserTrackingMode

func makeCoordinator() -> Coordinator {
Coordinator()
}

func makeUIView(context: Context) -> MKMapView {
context.coordinator.mapView
}

func updateUIView(_ uiView: MKMapView, context: Context) {
// MKMapView has a strange design that the delegate is called when setting manually so we need to prevent an infinite loop
context.coordinator.userTrackingModeChanged = nil
uiView.userTrackingMode = userTrackingMode == .follow ? MKUserTrackingMode.follow : MKUserTrackingMode.none
context.coordinator.userTrackingModeChanged = { mode in
userTrackingMode = mode == .follow ? MapUserTrackingMode.follow : MapUserTrackingMode.none
}
}

class Coordinator: NSObject, MKMapViewDelegate {

lazy var mapView: MKMapView = {
let mv = MKMapView()
mv.delegate = self
return mv
}()

var userTrackingModeChanged: ((MKUserTrackingMode) -> Void)?

func mapView(_ mapView: MKMapView, didChange mode: MKUserTrackingMode, animated: Bool) {
userTrackingModeChanged?(mode)
}
}
}

相关内容

  • 没有找到相关文章

最新更新