防止 updateUIView 在 @State var 更改时更新视图
Posted
技术标签:
【中文标题】防止 updateUIView 在 @State var 更改时更新视图【英文标题】:Prevent updateUIView to update view when @State var changes 【发布时间】:2021-12-28 23:14:11 【问题描述】:在阅读了其他问题和 google 之后,我认为可以肯定地说,只要 UIViewRepresentable 中的任何@state/@Binding var 发生更改,无论如何都会触发 updateUIView。就我而言,我不想在一个特定的@State var 上触发 updateUIView。
我在我的应用程序中使用谷歌地图,我使用@state/@Binding var 将一些位置列表数据传递给 UIViewRepresentable,updateUIView 执行列表迭代并在 mapView 上使用GMSCameraUpdate.fit(bounds,withPadding: 15.0)
显示位置标记。
现在我正在使用协调器来使用 GMSMapViewDelegate 方法,例如拖动、willMove 和 idleAt。我想在相机移动后触发 idleAt 后立即将一个 @State var 的布尔值传递回我的内容视图。布尔值被发送回 contentView,我可以触发我的 API 以获取新的位置数据列表并将其传递给 @State var。但是由于 bool 是一个 @State var 并且它已更新,因此仍会使用旧数据列表触发 updateUIView 并将相机移回旧位置边界。这个 updateUIView 甚至在 API 调用被触发之前就被触发了。
如何在不触发 updateUIView
的情况下将 bool 发送回我的 contentView?
UIView 可表示的代码
struct MapsView: UIViewRepresentable
@Binding var list : [LocationObj]
@Binding var shouldRefresh: Bool
func makeUIView(context: Context) -> GMSMapView
func updateUIView(_ mapView: GMSMapView, context: Context)
var bounds = GMSCoordinateBounds()
for location in list
mapView.animate(with: GMSCameraUpdate.fit(bounds,withPadding: 15.0))
func makeCoordinator() -> Coordinator
Coordinator(owner: self, refresh: $shouldRefresh)
class Coordinator: NSObject, GMSMapViewDelegate
let owner: MapsView
var mShouldRefresh: Binding<Bool>
init(owner: MapsView, refresh: Binding<Bool>)
self.owner = owner
self.mShouldRefresh = refresh
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition)
// after moving camera and calculating the difference
mShouldRefresh.wrappedValue = true
现在回到 contentView
@State var shouldRefresh = true
MapsView(list: $locationList, shouldRefresh: $shouldRefresh)
【问题讨论】:
那么不要使用绑定,而是可以注入闭包并调用它,不会调用更新,因为可表示不再依赖于该状态。 @Asperi 我不明白闭包在这里是如何工作的。你能写一些代码sn-p吗? 【参考方案1】:这是可能的方法的草图(内联编写,未经测试,因此可能是错字 - 编译器错误修复由您负责):
struct MapsView: UIViewRepresentable
@Binding var list : [LocationObj]
var callback: (Bool) -> Void // << here !!
func makeUIView(context: Context) -> GMSMapView
func updateUIView(_ mapView: GMSMapView, context: Context)
var bounds = GMSCoordinateBounds()
for location in list
mapView.animate(with: GMSCameraUpdate.fit(bounds,withPadding: 15.0))
func makeCoordinator() -> Coordinator
Coordinator(owner: self)
class Coordinator: NSObject, GMSMapViewDelegate
let owner: MapsView
init(owner: MapsView)
self.owner = owner
func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition)
// after moving camera and calculating the difference
owner.callback(true) // << here !!
和类似的用法
@State var shouldRefresh = true
MapsView(list: $locationList)
self.shouldRefresh = $0
【讨论】:
感谢您的时间,我会尝试更新。 我以MapsView(workersList: $locationList, callback: self.shouldRefresh = $0)
尝试了这个关闭,但updateUIView
仍然被解雇。有什么想法吗?以上是关于防止 updateUIView 在 @State var 更改时更新视图的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI MapKit 的 updateUIView 中添加“.setRegion”?
iOS 14 SwiftUI UIViewRepresentable updateUIView 没有检测到 ObservedObject 的变化?
为什么@EnvironmentObject强制重新初始化视图?