我有一个SwiftUI应用程序,其中包括MKMapView UIViewRepresentable。地图功能 允许用户通过创建航点来选择自己的路径。基本逻辑 效果很好,但是当某些更改发生时,我无法重绘地图 制作。具体来说,用户可以点击现有旅行/地图的路标注释,然后 选择在点击的项目之后添加新的航路点,或删除点击的项目。 奇怪的是,删除工作正常,但插入操作不起作用 导致重绘地图(视图中的计算距离也未更新)。 设计是一个基本的清单/详细信息,其中清单是行程和 详细信息是旅行的mapView。数据存储在核心数据中,并且 确实在删除或插入时正确更新, 但是同样,对于插入,地图不会更新,直到行程结束 然后重新打开。
对于插入,我在地图上覆盖了一个SwiftUI视图,该视图 包含一个目标(在地图中心)和一个用于插入该项目的按钮。的 用户移动地图,使新的航点位于目标下方,然后点按“插入”按钮。一世 希望在插入航路点后(通过按钮)重绘地图。
我想基本知识-有没有办法强制MKMapKit协议调用 func updateUIView(_视图:MKMapView,上下文:Context){} 从不是UIViewRepresentable的视图 和/或,如何在SwiftUI文件中获取对mapview的引用,该引用会调用 详情。似乎向后绑定应该起作用,但我没有成功。
此SwiftUI文件称为DetailMapView,它是UIViewRepresentable。 点击按钮会将坐标插入Core Data。
struct ComboDetailMapView: View {
@ObservedObject var udm: UserDefaultsManager
@Environment(\.presentationMode) var presentationMode
@State var thisMap: MKMapView?
let generator = UINotificationFeedbackGenerator()
var aTrip: Trip?
var body: some View {
GeometryReader { geo in
ZStack {
ZStack {
VStack {
Text(self.aTrip?.name ?? "Unknown Map Name")
.padding(.top, -50)
.padding(.bottom, -20)
DetailMapView(udm: self.udm, aTrip: self.aTrip)
.padding(.top, -20)
}//vstack
VStack {
Spacer()
ZStack {
RoundedRectangle(cornerRadius: 20)
.fill(Color.white).opacity(0.8)
.frame(width: geo.size.width - 20, height: 100)
Text(self.udm.tripTimeAndDistance)
//...bunch of modifiers
}
.padding(.bottom, 20)
}//vstack
}//to put time and distance on top
ZStack {
VStack {
Spacer()
HStack {
Spacer()
Button(action: {
self.generator.notificationOccurred(.success)
self.udm.showAddWaypointControls.toggle()
guard let guardTrip = self.aTrip else { return }
DetailMapView(udm: self.udm).insertNewWaypoint(insertTrip: guardTrip, centerCoordinate: self.udm.pubCenterCoordinate, name: "Center", subtitle: "Center", pinText: "Center", wayPointSequence: self.udm.insertSequenceNumber + 1)
}) {
Image(systemName: "plus")
}
//...bunch of modifiers
}
}//vstack
Circle()
//...modifiers
}//button and circle zstack
.offset(x: self.udm.showAddWaypointControls ? 0 : screen.width)
.animation(.easeInOut(duration: 1.0))
}//zstack
}//geo
}//body
}
DetailMapView:
struct DetailMapView: UIViewRepresentable {
let kAppDelegate = UIApplication.shared.delegate as! AppDelegate
@Environment(\.presentationMode) var presentationMode
@ObservedObject var udm: UserDefaultsManager
//bunch of @State variables
var aTrip: Trip?
class Coordinator: NSObject, MKMapViewDelegate {
var parent: DetailMapView
init(_ parent: DetailMapView) {
self.parent = parent
}
func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {
parent.udm.pubCenterCoordinate = mapView.centerCoordinate
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "CRSAnnotationView"
//...more code - all this works
return crsAnnotationView
}//viewfor
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if control == view.leftCalloutAccessoryView {
//...more code - all this works
} else if control == view.rightCalloutAccessoryView {
mapView.removeAnnotations(parent.annotations)
parent.annotations = []
//this displays the overlay with the target and the button to add the waypoint
parent.udm.showAddWaypointControls.toggle()
guard let guardTrip = parent.aTrip else { return }
for wp in guardTrip.waypoints {
//...code to sequence the waypoints in the Core Data NSSet - this all works
}//for wp in parent.aTrip!.waypoints
}//else if control == else if control
}//annotationView
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(polyline: overlay as! MKPolyline)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 4.0
return renderer
}//rendererFor
}//class coordinator
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> MKMapView {
//...housekeeping code for distance and time display - all works
self.udm.showAddWaypointControls = false
let mapView = MKMapView()
mapView.showsUserLocation = true
mapView.delegate = context.coordinator
udm.tripTimeAndDistance = "Calculating..."
return mapView
}
//This is called for deletions, but not for insertions:
func updateUIView(_ view: MKMapView, context: Context) {
redrawTheMap(trip: aTrip, mapView: view)
}//updateUIView
func doOneWaypointPolylineCallback(view: MKMapView, source: CLLocationCoordinate2D, destination: CLLocationCoordinate2D, callback: @escaping (Double, Double) -> Void) {
//this code gets distance and time for each segment and works
}//doOneWaypointPolylineCallback
func modifyTheWaypointList(trip: Trip?, mapView: MKMapView, view: MKAnnotationView) {
//this code deleted the waypoint from Core Data and works
}//modifyWayList
func redrawTheMap(trip: Trip?, mapView: MKMapView) {
//...this code cycles through the waypoints to add annotations and overlays - it works
}//redrawTheMap
}//struct DetailMapView
任何指导将不胜感激。
Xcode版本11.3.1(11C504