代码之家  ›  专栏  ›  技术社区  ›  JohnSF

带有MKMapView映射的SwiftUI在更改后不会更新

  •  0
  • JohnSF  · 技术社区  · 4 年前

    允许用户通过创建航路点来选择自己的路径。基本逻辑 工作很好,但我无法使地图重画时,某些变化 制造的。具体来说,用户可以点击现有行程/地图的航路点注释 选择在点击的项目之后添加一个新的航路点,或者删除点击的项目。 设计是一个基本列表/细节,其中列表是行程和 细节是一次旅行的地图视图。数据存储在核心数据中 确实在删除或插入时正确更新, 然后重新开放。

    对于插入,我用一个简单的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
    

    如有任何指导,我们将不胜感激。

    0 回复  |  直到 4 年前
    推荐文章