我正在处理一个应用程序,我必须将 MKMapView
(UIKit) 嵌入到 SwiftUI View 中。不幸的是,我不能使用 SwiftUI 的实现 Map
,因为我必须支持集群(Map
目前无法支持)。
问题是,MKMapView
不反射(reflect)应用于数据源(persons
数组)的更改。
内容 View
struct ContentView: View {
@State private var persons: [Person] = [
.init(
coordinate: .init(latitude: 50.7123012, longitude: 5.1231021),
title: "Person 1"
),
.init(
coordinate: .init(latitude: 49.3123012, longitude: 5.1231021),
title: "Person 2"
)
]
var body: some View {
VStack {
MapView(persons: $persons)
Button("Remove Person at index 0") {
persons.remove(at: 0)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
借助 UIViewRepresentable
实现 MKMapView
:
struct MapView: UIViewRepresentable {
@Binding var persons: [Person]
private let mapView = MKMapView()
init(persons: Binding<[Person]>) {
self._persons = persons
// other stuff
}
func makeUIView(context: Context) -> MKMapView {
mapView.delegate = context.coordinator
mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: "testAnnotation")
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
DispatchQueue.main.async {
mapView.removeAnnotations(mapView.annotations)
mapView.addAnnotations(persons)
}
}
}
extension MapView {
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, MKMapViewDelegate {
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "testAnnotation", for: annotation) as? MKMarkerAnnotationView {
annotationView.glyphImage = UIImage(systemName: "person")
return annotationView
}
return nil
}
}
}
演示模型:
class Person: NSObject, MKAnnotation {
var coordinate: CLLocationCoordinate2D
let title: String?
init(coordinate: CLLocationCoordinate2D, title: String?) {
self.coordinate = coordinate
self.title = title
}
}
请注意,这是一个简化的实现,我删除了集群等逻辑以专注于问题。
如果您点击“删除索引 0 处的人员”,它实际上会删除索引 0 处的条目,但不幸的是 map 没有更新。问题是 MapView
中的 updateUIView
没有被调用,我不确定为什么会这样。
感谢您的帮助:-)...
最佳答案
两个问题在 makeView
中创建 map View - 这是一个设计的地方,在更新中更新注释(不需要延迟)它是一个调用绑定(bind)更新的地方,以更新 UIView 对应物(所有 UI 失效/刷新都是自动进行的)
所以,这里是固定版本。使用 Xcode 13.4/iOS 15.5 测试
struct MapView: UIViewRepresentable {
@Binding var persons: [Person]
init(persons: Binding<[Person]>) {
self._persons = persons
// other stuff
}
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView() // << here !!
mapView.delegate = context.coordinator
mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: "testAnnotation")
return mapView
}
func updateUIView(_ mapView: MKMapView, context: Context) {
mapView.removeAnnotations(mapView.annotations) // << here !!
mapView.addAnnotations(persons)
}
}
关于ios - UIViewRepresentable - MKMapView 没有得到更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73040979/