ios SwiftUI如何以及何时重新计算body?SwiftUI View的生命周期是什么?

cbwuti44  于 11个月前  发布在  iOS
关注(0)|答案(1)|浏览(141)

看看这个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

7uzetpgm

7uzetpgm1#

后面是Apple Demystify SwiftUI。这就是他们所说的dependency graph
这个图的秘密在于,如果依赖关系发生了变化,只有那些视图会被无效。SwiftUI会调用每个视图的主体,为每个视图生成一个新的主体值。SwiftUI会示例化每个无效视图主体的值。视图的值是短暂的。但是视图本身有更长的生命周期。
所以SwiftUI中的每个视图都会有一个标识,这个标识在graph中涉及。当graph决定生成新的body时,它会找到正确的视图的标识。然后只更新需要新body的视图。

相关问题