Search code examples
swiftuibindingstateproperty-wrapper

How to initialize a @State variable using the value of a variable that comes from another view SWIFTUI


I need to initialize a @State variable using the value that comes from another view. Since my code is very long, I put a simplified code:

struct IconoLista: View {

    // MARK: Variables generales
       
    @State var listaElegida : Listas = Listas()
    var body: some View {
        VStack {
            NavigationLink("",destination: ProductosEnLista(listaElegida: self.listaElegida), tag: "ProductosEnLista", selection: $selectionLista)
            Button(action: {self.listaElegida = datosLista;self.selectionLista = "ProductosEnLista"})
            { 
                Image("personal")
                .resizable()
                .frame(alignment: .center)   
            }
            Text("Elegido")
                    .frame(alignment: .center)
                    .foregroundColor(.black)
                    .font(Font.system(size: 10.0, weight: .bold, design: .default))
        }
        .frame(width: 72, height: 100, alignment: .center)
    }
}

struct ProductosEnLista : View {
    var listaElegida : Listas

    @State var contenido : Array<Contenido> = Contenido().datos(idLista : listaElegida.id)
}

This line is my problem since, as is normal, until I am in the body of the view (var body: some View), I do not have the value of listaElegida available.

@State var contenido : Array<Contenido> = Contenido().datos(idLista : listaElegida.id)

I have tried everything I have read, doing in the second view listaElegida as @Binding, I try to assign the value inside the var body : some View And it's all mistakes


Solution

  • In ProductosEnLista, you cannot use listaElegida before ProductosEnLista is fully initialized. That means, you cannot use listaElegida in your declaration @State var contenido : Array<Contenido> = Contenido().datos(idLista : listaElegida.id).

    To "fix" this, you can create your own init(...) (as mentioned in the comment), where you make sure listaElegida is initialized before you use it to construct your contenido.

    struct ProductosEnLista: View {
        var listaElegida: Listas
        @State var contenido: [Contenido]
        
        init(listaElegida: Listas) {
            self.listaElegida = listaElegida
            _contenido = State(initialValue: Contenido().datos(idLista: listaElegida.id))
        }
        
        var body: some View {
            Text("all good now")
        }
    }