问题描述
在我的 SwiftUI 视图中,我使用通过 UIViewRepresentable 协议包装的 MKMapView。在地图上我有一个注释,当我选择它并将应用程序最小化到后台时,注释会自动再次取消选择。如果使用 UIKit,则此行为会有所不同,在同一情况下,注释不会变为未选中状态。是否可以使用 SwiftUI 实现相同的行为?
这是我的 SwiftUI 地图代码
struct MapView: UIViewRepresentable {
private var mapView = MKMapView()
let coordinates = CLLocationCoordinate2D(latitude: 40.785091,longitude: -73.968285)
func makeUIView(context: UIViewRepresentableContext<MapView>) -> MKMapView {
mapView.delegate = context.coordinator
mapView.showsUserLocation = true
mapView.userTrackingMode = .follow
let region = MKCoordinateRegion(center: coordinates,latitudinalMeters: 1000,longitudinalMeters: 1000)
mapView.setRegion(region,animated: false)
return mapView
}
func updateUIView(_ uiView: MKMapView,context: UIViewRepresentableContext<MapView>) {
addAnnotations()
}
func makeCoordinator() -> MapView.Coordinator {
return Coordinator(self)
}
private func addAnnotations() {
mapView.removeAnnotations(mapView.annotations)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinates
mapView.addAnnotation(annotation)
}
}
extension MapView {
final class Coordinator: NSObject,MKMapViewDelegate {
let parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
func mapView(_ mapView: MKMapView,didSelect view: MKAnnotationView) {
debugPrint("Select annotation")
}
func mapView(_ mapView: MKMapView,diddeselect view: MKAnnotationView) {
debugPrint("deselect annotation")
}
}
}
解决方法
我发现每次app回到前台时都会调用UIViewRepresantable方法(为什么?)这意味着每次发生这种情况时都会删除注释并重新添加。所以基本上您需要做的就是确保您尝试添加到地图的注释尚未显示在那里。如果新注释不包含某些已显示的注释,则您必须将其删除。
我是这样处理的:
func updateUIView(_ uiView: MKMapView,context: UIViewRepresentableContext<SCMapView>) {
createAnnotations(uiView)
}
private func createAnnotations(_ view: MKMapView) {
let oldAnnotations = view.annotations
var newAnnotations: [PostAnnotation] = viewStore.annotations
if !oldAnnotations.isEmpty {
for annotation in oldAnnotations {
if let postAnnotation = annotation as? PostAnnotation {
if !newAnnotations.contains(where: { $0.post.id == postAnnotation.post.id }) {
view.removeAnnotation(postAnnotation)
} else {
newAnnotations.removeAll(where: { $0.post.id == postAnnotation.post.id })
}
}
}
}
if !newAnnotations.isEmpty {
view.addAnnotations(newAnnotations)
}
}