ios SwiftUI工作表在首次出现时不会访问状态变量的最新值

3z6pesqy  于 2022-12-15  发布在  iOS
关注(0)|答案(2)|浏览(261)

第一次显示工作表时,状态变量似乎未正确更新。
例如,使用以下代码:

import SwiftUI

struct DemoView: View {
    @State var showDetails: Bool = false
    var body: some View {
        VStack {
            Button(action: {
              showDetails = true
            }) {
                Text("Show sheet")
            }
        }.sheet(isPresented: $showDetails){
            VStack {
                Text("showDetails: \(showDetails ? "yes" : "no")")
            }
        }
    }
}

struct DemoView_Previews: PreviewProvider {
    static var previews: some View {
        DemoView()
    }
}

第一次单击时将显示“no”,第二次单击时将显示“yes”,如下所示:

我错过了什么吗?我如何确保我的状态变量被工作表视图正确读取?

ou6hu8tu

ou6hu8tu1#

您可以看到工作表创建时间的值。如果要跟踪父视图状态,请创建绑定到该状态的工作表子视图,如下所示。绑定将在子视图出现时更新子视图。
使用Xcode 12 / iOS 14进行测试
使用Xcode 13.3 / iOS 15.4重新测试

struct DemoView: View {
    @State var showDetails: Bool = false
    var body: some View {
        VStack {
            Button(action: {
              showDetails = true
            }) {
                Text("Show sheet")
            }
        }.sheet(isPresented: $showDetails){
            SheetDetailView(flag: $showDetails)
        }
    }
}

struct SheetDetailView: View {
    @Binding var flag: Bool
    var body: some View {
        VStack {
            Text("showDetails: \(flag ? "yes" : "no")")
        }
    }
}
vh0rcniy

vh0rcniy2#

有时候不可能使用@Binding。例如,如果我们需要在init块中使用变量。我的方法是:

struct DemoView: View {

    @State var showDetails = false
    @State var wtfGuys = false

    var body: some View {
        VStack {
            Button(action: {
                showDetails = true
            }) {
                Text("Show sheet")
            }
        }
                .sheet(isPresented: $showDetails) {
                    ZStack {
                        if wtfGuys {
                            VStack {
                                Text("showDetails: \(showDetails ? "yes" : "no")")
                            }
                        }
                    }
                            .onAppear { wtfGuys = true }
                            .onDisappear { wtfGuys = false }
                }
    }
}

初始化块示例:

struct DemoView: View {

    @State var showDetails = false
    @State var wtfGuys = false

    var body: some View {
        VStack {
            Button(action: {
                showDetails = true
            }) {
                Text("Show sheet")
            }
        }
                .sheet(isPresented: $showDetails) {
                    ZStack {
                        if wtfGuys {
                            DetailView(showDetails: showDetails)
                        }
                    }
                            .onAppear { wtfGuys = true }
                            .onDisappear { wtfGuys = false }
                }
    }
}

struct DetailView: View {

    let showDetails: Bool

    init(showDetails: Bool) {
        print(showDetails) // true
        self.showDetails = showDetails
    }

    var body: some View {
        Text("showDetails: \(showDetails ? "yes" : "no")")
    }
}

还有一个案例:

struct DemoView: View {

    @State var showDetails = false
    @State var detailsText = ""

    var body: some View {
        VStack {
            Button(action: {
                detailsText = "new text"
                showDetails = true
            }) {
                Text("Show sheet")
            }
        }
                // Here it is
                .onChange(of: showDetails) { _ in }
                .sheet(isPresented: $showDetails) {
                    Text("text: \(detailsText)")
                }
    }
}

相关问题