Home > Enterprise >  Swift: Modify struct property out of scope
Swift: Modify struct property out of scope

Time:12-12

I've isolated the problem as best I can. I have no idea why the following code doesn't work as expected, I've tried everything I can think of for such a simple error. I think it has to do with the @State variable?

Expected functionality: There is a view with a button on it. When the button is pressed, an overlapping view covers the original view. When the back button on the overlapping view is pressed, the overlapping view goes away.

Actual Functionality: The button to show the view works, but pressing the back button does not make the overlapping view go away.

Code:

struct MainView: View {
    @State var showOverlap = false
    
    var body: some View {
        ZStack {
            Button(action: {
                showOverlap = true
            }) {
                Text("Button")
            }
            if showOverlap {
                Overlap()
            }
        }
    }
}


struct Overlap: View {
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 40)
                .aspectRatio(130/200, contentMode: .fit)
                .foregroundColor(.gray)
            
                Button(action: {
                    MainView.showOverlap = false
                }, label: {
                    Text("Back")
                })
        }
    }
}

CodePudding user response:

Right now, you're trying to access showOverlap as if it is a static variable on MainView -- this won't work since it is not a static property and even if it were, you would need a reference to the specific instance of MainView you were showing -- something that in SwiftUI we generally avoid since Views are transitive.

Instead, you can pass a Binding -- this is one of the ways of passing state for parent to child views in SwiftUI.


struct MainView: View {
    @State var showOverlap = false
    
    var body: some View {
        ZStack {
            Button(action: {
                showOverlap = true
            }) {
                Text("Button")
            }
            if showOverlap {
                Overlap(showOverlap: $showOverlap) //<-- Here
            }
        }
    }
}


struct Overlap: View {
    @Binding var showOverlap : Bool  //<-- Here
    
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 40)
                .aspectRatio(130/200, contentMode: .fit)
                .foregroundColor(.gray)
            
                Button(action: {
                   showOverlap = false //<-- Here
                }, label: {
                    Text("Back")
                })
        }
    }
}
  • Related