首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UIViewRepresentable - MKMapView不更新

UIViewRepresentable - MKMapView不更新
EN

Stack Overflow用户
提问于 2022-07-19 17:07:20
回答 1查看 181关注 0票数 3

我正在处理一个应用程序,我必须将MKMapView (UIKit)嵌入到SwiftUI视图中。不幸的是,我不能使用已实现的Map of SwiftUI,因为我必须支持集群( Map目前不能这样做)。

问题是,MKMapView没有反映应用于数据源(persons数组)的更改。

ContentView

代码语言:javascript
复制
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()
    }
}

基于MKMapView UIViewRepresentable**:**的的实现

代码语言:javascript
复制
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
        }
    }
}

演示模型:

代码语言:javascript
复制
class Person: NSObject, MKAnnotation {
    var coordinate: CLLocationCoordinate2D
    let title: String?
    
    init(coordinate: CLLocationCoordinate2D, title: String?) {
        self.coordinate = coordinate
        self.title = title
    }
}

请注意,这是一个简化的实现,在这个实现中,我删除了用于集群等的逻辑,以关注问题.。

如果点击“移除索引0处的Person”,它实际上删除了索引0处的条目,但遗憾的是地图没有更新。问题是updateUIView in MapView没有被调用,我不知道为什么会这样。

谢谢你的帮助:-)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-19 17:24:54

有两个问题在makeView中创建地图视图--通过设计,在更新中正确地更新注释(不需要延迟)--这是一个调用绑定更新来更新UIView副本的地方(所有UI无效/刷新都是自动完成的)

这是固定版本。用Xcode 13.4 / iOS 15.5测试

代码语言:javascript
复制
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)

    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73040979

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档