iOS SwiftUI UIViewRepresentable updateUIView 找出哪些属性实际上发生了变化?

ear*_*org 6 ios swift swiftui

我想知道当调用 updateUIView 时如何测试 UIViewRepresentable 中的 @Binding 和 @StateObject 实际上发生了变化?

我正在实现 MKMapView,并且不想一直更新注释,仅当 StateObject 更改时才更新。

所以我想做这样的事情:

struct MapView: UIViewRepresentable
{
    @ObservedObject var annotations:MyAnnotations
    @ObservedObject var region:MKCoordinateRegion

    func updateUIView(_ view: MKMapView, context: Context)
    {
        if annotations.changed == true
        {
            // ... update annotations
        }
        
        if (region.changed == true
        {
            // ... update region
        }
    }
}
    
Run Code Online (Sandbox Code Playgroud)

一直更新注释会给渲染带来一些麻烦,我想避免这种情况。这可能是关于 UIViewRepresentables 的一个相当普遍的问题,旨在用于优化更新。

twa*_*way 7

我过去处理这个问题的方法是将属性的当前值存储在我的 context.coordinator 中。然后,在 updateUIView 中,您可以根据缓存值检查新值以查看它是否已更改。我不喜欢这个解决方案,但它是我发现的最好的解决方案。

像这样的东西:

struct MapView: UIViewRepresentable
{
    @ObservedObject var annotations:MyAnnotations
    @ObservedObject var region:MKCoordinateRegion

    func updateUIView(_ view: MKMapView, context: Context)
    {
        if annotations != context.coordinator.cachedAnnotations
        {
            // ... update view
            context.coordinator.cachedAnnotations = annotations
        }
    
        if (region != context.coordinator.cachedRegion)
        {
            // ... update view
            context.coordinator.cachedRegion = region
        }
    }
        
    class Coordinator {
        var cachedAnnotations: MyAnnotations
        var cachedRegion: MKCoordinateRegion
    
        init() {
            // ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)