SwiftUI将数据从UIViewRepresentable传递到SwiftUI的View

时间:2020-10-18 11:28:53

标签: swiftui

我正在编写自定义滚动视图以启用图像缩放和定位。由于它将在SwiftUI视图中使用,因此我遵循UIViewRepresentable。我试图获取滚动视图的zoomScale属性和contentOffset,以确定确切的图像外观(当前缩放和定位)。如果图像没有缩放也没有不同的位置,通常为1.0和(0,0)。

我面临的问题是,如果我将绑定传递到缩放比例更改或contentOffset更改时更改的视图中,则该视图将被重绘(当刷新@State时)。这会导致诸如“在更新视图时更新状态”错误之类的问题。

再次调用makeUIView重置的contentOffset和zoom比例。如果我也在那里重复使用值,我们几乎会陷入事件循环。

Scale changes -> Binding changes -> State changes -> Redraw UI -> Scale changes ...

在SwiftUI中,当数据发生更改时,是否有任何方法可以将数据从视图中传递出来而不刷新它?那么ViewPreferences呢?他们可以工作吗?

当“超级视图”中任何其他不相关的@State更改,scale和contentOffset都被重置时,会发生另一个问题,所以我有点需要将绑定传递到该视图中。

谢谢

1 个答案:

答案 0 :(得分:0)

我发现的一种方法是向您的协调器添加一个“shouldUpdateState”布尔值。

当比例发生变化时,将 shouldUpdateState 设置为 false。

然后设置绑定。

updateUIView 方法的第一行应该是

guard context.coordinator.shouldUpdateState else {
    context.coordinator.shouldUpdateState = true
    return
}

它有点像hacky解决方案...不幸的是,似乎没有任何好的方法来管理这个。

另一种可能有效的替代方法(我还没有测试过)是使用像这样的可观察对象。

class ViewModel: ObservableObject {
    @Published var zoomScale: CGFloat
}

在你的 UIViewRepresentable 里面

// Note we aren't using @ObservedObject here. 
// It shouldn't trigger view reloads when you update your viewModel. 
// But it will still trigger them in your swiftUI views.
var viewModel: ObservableObject<ViewModel>

init(viewModel: ObservableObject<ViewModel>) {
    self._viewModel = viewModel
}