提问人:Jerry 提问时间:11/17/2023 最后编辑:Jerry 更新时间:11/17/2023 访问量:78
SwiftUI 将如何以及何时重新计算正文?SwiftUI View 的生命周期是什么?
How and When the SwiftUI will recalculate the body? What's SwiftUI View's lifecircle?
问:
请看这个演示:
struct ColorView:View {
@State var changed = false
init(){
print("ColorView init")
}
var body: some View {
print("calculate ColorView's body")
return ZStack{
Rectangle()
.foregroundStyle(changed ? Color.red : Color.blue)
Button(changed.description) {
changed.toggle()
print("ColorView's color changed")
}
.foregroundStyle(Color.black)
}
}
}
struct ListView:View {
init(){
print("ListView init")
}
var body: some View {
print("calculate ListView's body")
return ZStack{
ScrollView {
VStack{
ForEach(1..<30) { index in
Text("\(index)")
.frame(width: screenWidth, height: 50)
}
}
}
}
}
}
enum Tabs{
case list,color
}
struct ContentView: View {
@State var tab = Tabs.list
var body: some View {
ZStack {
switch tab {
case .list:
ListView()
case .color:
ColorView()
}
VStack{
Spacer()
Button("Change") {
print("change page")
tab = tab == .list ? .color : .list
}
.padding()
.background {
Color.white
}
}
}
}
}
以下是我的一些疑问:
1 当我切换页面时,SwiftUI 会创建一个新的视图实例,但视图的主体并不总是重新计算。
2 ListView 和 ColorView 是不同的视图,没有共享状态。默认视图为 ListView。每次更改选项卡时,都会重新计算 ColorView 的正文,但不会重新计算 ListView 的正文。当我更改 ColorView 中更改的 @State 属性时,ListView 的正文会在每次选项卡更改时重新计算,但 ColorView 的正文不会。
3 尽管是不同的实例或正在重新计算正文,但 ColorView 始终会根据更改的属性显示正确的颜色。但是,每当重新计算 ScrollView 的正文时,ListView 都会重置其滚动位置。
这是我在终端中运行的结果:
-change page
-ColorView init
-calculate ColorView's body
-change page
-ListView init
-change page
-ColorView init
-calculate ColorView's body
-change page
-ListView init
-change page
-ColorView init
-calculate ColorView's body
-ColorView's color changed #tap the button in ColorView
-calculate ColorView's body
-change page
-ListView init
-calculate ListView's body #the offset of ScrollView is reset
-change page
-ColorView init
-change page
-ListView init
-calculate ListView's body
#ColorView always have the correct color of all the case
答:
0赞
son
11/17/2023
#1
紧随其后的是 Apple 揭开 SwiftUI 的神秘面纱。这就是他们所说的dependency graph
该图的秘密在于,如果依赖项发生变化,则只有这些视图才会失效。SwiftUI 将调用每个视图的正文,为每个视图生成一个新的正文值。SwiftUI 将实例化每个无效视图正文的值。视图的值是短暂的。但视图本身具有更长的生命周期。
因此,SwiftUI 中的每个视图都会有一个标识,该标识涉及 .当决定生成一个新机构时,它会找到正确观点的身份。然后仅更新需要新主体的视图。graph
graph
评论
0赞
Jerry
11/17/2023
我知道这一点,但是看看代码和结果,我无法理解我何时更改页面,它们具有不同的状态,并且我更改了ColorView中的属性,ListView将在每次选项卡更改时更改其行为
0赞
son
11/17/2023
我不知道你为什么会遇到这个问题。我尝试在 iOS 16.2 上运行。打印日志符合预期。在列表和颜色之间切换后,总是会再次生成选项卡内容,因为没有任何东西可以保存它。ColorView 中的颜色将重置为 false,ListView 内容偏移量也将重置为 0。也许你想清理和重新构建。
0赞
Jerry
11/17/2023
是的,你是对的。我只是在模拟器或真实设备上尝试它,它按预期工作。问题仅在 Xcode 中的预览画布上。似乎预览不可靠:(。非常感谢
0赞
son
11/17/2023
很高兴我能帮上忙。
评论