我正在编写自定义滚动视图以启用图像缩放和定位。由于它将在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都被重置时,会发生另一个问题,所以我有点需要将绑定传递到该视图中。
谢谢
答案 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
}