[英]SwiftUI EnvironmentObject does not redraw the current view but its parent view
我試圖了解@EnvironmentObject
在ObservableObject
中的屬性更改時如何影響重繪。
根據 Apple 關於EnvironmentObject的文檔,
每當可觀察對象發生變化時,環境對象都會使當前視圖無效。
如果上述陳述為真,那么當您按下ContentView
中的按鈕時,下面的代碼不會使ChildView
失效並重新創建。 這應該打印以下輸出。
initializing parent
initializing child
// after pressing the button
initializing child
與我的上述假設相反,它實際上打印
initializing parent
initializing child
// after pressing the button
initializing parent
誰能解釋為什么會這樣? 為什么ParentView
被重新創建,即使ParentView
不依賴於Library
?
class Library: ObservableObject {
@Published var item: Int = 0
}
struct ContentView: View {
@StateObject var library: Library = Library()
var body: some View {
VStack {
ParentView()
.environmentObject(library)
Button {
library.item += 1
} label: {
Text("increment")
}
}
}
}
struct ParentView: View {
init() {
print("initializing parent")
}
var body: some View {
VStack {
Text("Parent view")
ChildView()
}
}
}
struct ChildView: View {
@EnvironmentObject var library: Library
init() {
print("initializing child")
}
var body: some View {
Text("Child view")
}
}
SwiftUI View 可能有點棘手。
每當可觀察對象發生變化時,環境對象都會使當前視圖無效。
並不意味着對象本身被重新創建。 它只是意味着視圖的主體被調用並且視圖自身重建。
請記住,結構不是View
本身,它只是一個“描述”。
我添加了一些打印語句以使這一點更清楚:
struct ContentView: View {
@StateObject var library: Library = Library()
init(){
print("initializing content")
}
var body: some View {
VStack {
let _ = print("content body")
ParentView()
.environmentObject(library)
Button {
library.item += 1
} label: {
Text("increment")
}
}
}
}
struct ParentView: View {
init() {
print("initializing parent")
}
var body: some View {
VStack {
let _ = print("parent body")
Text("Parent view")
ChildView()
}
}
}
struct ChildView: View {
@EnvironmentObject var library: Library
init() {
print("initializing child")
}
var body: some View {
let _ = print("child body")
Text("child")
}
}
這最初打印:
initializing content
content body
initializing parent
parent body
initializing child
child body
按下按鈕后:
content body
initializing parent
child body
正如您所見,這些View
的主體取決於Library
,它們各自的主體被重新評估。
ParentView
初始化程序運行是因為在您的ContentView
中,您在正文中調用ParentView()
,因此創建了一個“描述”您的 View 的新結構。 ParentView
的視圖本身保持不變,因此不會調用其body
var。
這個關於 SwiftUI 視圖的WWDC 2021視頻將幫助您更好地理解這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.