有人应该重新呈现.sheet
的闭包吗?即使整个body
中的任何内容导致更新,即使它不在层次结构中,也应该真的这样做吗?
例如,其中cartItemModal
是一个@State
属性,它没有被更新:
var body: some View {
VStack {
theCartView
// even putting the sheet outside of the cart view entirely, it still gets re-rendered
Text("").sheet(item: $cartItemModal) { (productWithCartItem) -> QuickAddView in
QuickAddView(viewModel: QuickAddViewModel(productDetails: productWithCartItem, cartAPIProvider: self.cartAPIProvider))
}
}
}
我的模态中的控件可以更新驱动theCartView
的基础列表中的数据。数据实际上不会影响我的QuickAddView
模态,该模态已使用其自己的结构进行渲染。但是,再次调用了该闭包,并且重新渲染了我的模态。
在此处添加完整的示例:
https://gist.github.com/sprynmr/66811b088ac50d9f297471d5c70d0eb3
我认为我的问题归结为:与基础数据更改无关或通过诸如@State
之类的运算符驱动的视图中的瞬时.sheet
属性如何?如果要在body
中的任何内容更新时随时重新创建这些内容,那么很多人可能会因其瞬态视图状态被重置而苦苦挣扎。
考虑一个计时器触发,该计时器触发从服务器获取更新并更新正在显示.sheet
的列表。将重新创建工作表,并重置@State
。
答案 0 :(得分:1)
您的工作表不会被重新渲染,但是每次您的工作表绑定到的任何内容发生突变时,它都会得到重新评估。这是预期的行为。
答案 1 :(得分:1)
SwiftUI视图是值类型。以任何方式修改它们都会创建一个新的视图,就像修改数组会创建一个新的数组一样。但是SwiftUI视图仅仅是数据。它们不代表UIViews等屏幕上显示的实际内容。重新计算View层次结构后,SwiftUI计算差异并将其应用于内部状态,并呈现所有更改(可能涉及动画)。
这意味着您在body
闭包中计算的任何内容都必须是快速的,因为您应该期望对其进行多次评估。如果可能的话,它通常也应该是惰性的,以避免在实际上不必要的情况下重新计算它。 (像ForEach
和List
这样的结构都是这种方式的惰性。)
同样重要的是,计算View不会产生任何副作用,也不依赖于全局状态。您无法控制何时对其进行评估,因此您的视图必须仅依赖SwiftUI数据(例如直接传递给视图的状态,环境和值)。