SwiftUI @State var not sync in .popover

struct ContentView: View {
    @State var visable: Bool = false
    @State var visableHiddenMenu: Bool = false

    var body: some View {
        VStack {
            Button("xxxx") {
                visableHiddenMenu = true
                print("visableHiddenMenu \(visableHiddenMenu)")
                visable.toggle()
            }
            .popover(isPresented: $visable) {
                VStack {
                    let _ = print("visableHiddenMenu2 \(visableHiddenMenu)")
                    Text("xxxx")
                }
                .onAppear {
                    print("appear \(visableHiddenMenu)")
                    visableHiddenMenu = visableHiddenMenu
                }
            }
        }
        .padding()
    }
}

the print is

visableHiddenMenu true
visableHiddenMenu2 false
appear true

so why visableHiddenMenu2 print false?

That code is running in willSet for the property.

Really strange. Not sure of the explanation, but looks like the VStack is not reevaluated when popover is called.

But, if added a Text in the VStack, and it works OK. VStack is reevaluated.

    var body: some View {
        VStack {
            Button("xxxx") {
                print("Button")
                visableHiddenMenu = true
                print("visableHiddenMenu \(visableHiddenMenu)")
                visable.toggle()
            }
            .popover(isPresented: $visable) {
                VStack {
                    let _ = print("visableHiddenMenu2 \(visableHiddenMenu)")
                    Text("Popover presented \(visableHiddenMenu)")
                }
                .onAppear {
                    print("appear \(visableHiddenMenu)")
                    visableHiddenMenu = visableHiddenMenu
                }
            }
            Text("Popover visible \(visableHiddenMenu)")
        }
        .padding()
    }

In log:

Button
visableHiddenMenu true
visableHiddenMenu2 true
appear true
visableHiddenMenu2 true

Note that visableHiddenMenu2 true appears twice, showing Stack is reevaluated.

PS: what is the purpose of line 19 ?

The notification happens using publishing. Only items included in the publishing notification will reflect the new state.

This is odd, I notice you get the expected value when the content of the Popover is in an enclosing struct. For example:

struct SheetView: View {
    @Binding var visableHiddenMenu: Bool

    var body: some View {
        VStack {
            let _ = Self._printChanges()
            Text("xxxx")
        }
        .printOutput(visableHiddenMenu)
        .onAppear {
            print("appear \(visableHiddenMenu)")
            visableHiddenMenu = visableHiddenMenu
        }
    }
}
struct ContentView: View {
    @State private var visable = false
    @State private var visableHiddenMenu = false

    var body: some View {
        VStack {
            let _ = Self._printChanges()

            Button("xxxx") {
                visableHiddenMenu = true
                print("visableHiddenMenu \(visableHiddenMenu)")
                visable.toggle()
            }
            .popover(isPresented: $visable) {
                SheetView(visableHiddenMenu: $visableHiddenMenu)
            }
        }
        .padding()
    }
}

extension View {
    func printOutput(_ value: Any) -> Self {
        print("visableHiddenMenu2 \(value)")
        return self
    }
}

Could you please open a bug report, include the code snippet that reproduces the issue and post the FB number here once you do. Bug Reporting: How and Why? has tips on creating your bug report.

SwiftUI @State var not sync in .popover
 
 
Q