允许用户通过创建航路点来选择自己的路径。基本逻辑
工作很好,但我无法使地图重画时,某些变化
制造的。具体来说,用户可以点击现有行程/地图的航路点注释
选择在点击的项目之后添加一个新的航路点,或者删除点击的项目。
设计是一个基本列表/细节,其中列表是行程和
细节是一次旅行的地图视图。数据存储在核心数据中
确实在删除或插入时正确更新,
然后重新开放。
对于插入,我用一个简单的SwiftUI视图覆盖地图
包含一个目标(在地图的中心)和一个用于插入项目的按钮。这个
用户移动地图,使新的航路点位于目标下方,然后点击插入按钮。我
希望在插入航路点后(通过按钮)重新绘制地图。
func updateUIView(\视图:MKMapView,上下文:context){}
和/或,如何在调用
细节。似乎向后绑定应该有效,但我没有成功。
这个SwiftUI文件调用DetailMapView,它是UIViewRepresentable。
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
}
详细地图视图:
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
如有任何指导,我们将不胜感激。