Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

@State variable doesn't change its value or re-render the view

I’m trying to change a @State from its parent but nothing is changed in the view.
I have a simple CustomView with an enum that control its content:

struct CustomView: View {
    enum ViewType: String {
        case first, second, third
    }
    
    @State var viewType: ViewType
    
    var body: some View {
        content
    }
    
    @ViewBuilder private var content: some View {
        switch viewType {
        case .first:
            Text("The first view")
        case .second:
            Text("The second view")
        case .third:
            Text("The last view")
        }
    }
}

And a superview with a button that tries to change its viewType value.

struct ContentView: View {
    let customView = CustomView(viewType: .first)
    var body: some View {
        VStack(spacing: 40) {
            customView
            Button("Change") {
                customView.viewType = .second
            }
        }
    }
}

Maybe I shouldn’t use @State but I had no success using Binding with enums.
Any idea?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Your suspicion about using a @Binding was correct — the parent view should own the @State and pass it down to the child view.


enum ViewType: String {
    case first, second, third
}

struct ContentView: View {
    @State var viewType: ViewType = .first
    
    var body: some View {
        VStack(spacing: 40) {
            CustomView(viewType: $viewType)
            Button("Change") {
                viewType = .second
            }
        }
    }
}

struct CustomView: View {
    
    @Binding var viewType : ViewType
    
    var body: some View {
        content
    }
    
    @ViewBuilder private var content: some View {
        switch viewType {
        case .first:
            Text("The first view")
        case .second:
            Text("The second view")
        case .third:
            Text("The last view")
        }
    }
}

In general, by the way, it’s not a good idea to try to store references to Views like you did with let customView = CustomView(viewType: .first). Instead, the View should be declared in the hierarchy and its state should be passed via parameters (including @Bindings).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading