看看这个demo:
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始终根据更改的属性显示正确的颜色。但是,ListView在其主体重新计算时会重置ScrollView的滚动位置。
下面是我在终端中运行的结果:
-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
型
1条答案
按热度按时间7uzetpgm1#
后面是Apple Demystify SwiftUI。这就是他们所说的
dependency graph
这个图的秘密在于,如果依赖关系发生了变化,只有那些视图会被无效。SwiftUI会调用每个视图的主体,为每个视图生成一个新的主体值。SwiftUI会示例化每个无效视图主体的值。视图的值是短暂的。但是视图本身有更长的生命周期。
所以SwiftUI中的每个视图都会有一个标识,这个标识在
graph
中涉及。当graph
决定生成新的body时,它会找到正确的视图的标识。然后只更新需要新body的视图。