persistent value in a picker changing views in SwiftUI

Viewed 185

I don't understand how implementing in SwiftUI a simple picker showing a list of values that retain the selected value switching between different views. I'm able to use the selected value to update the Model via Combine framework by the way.

here's the code, but the onAppear{}/onDisappear{} doesn't work as expected:

struct CompanyView: View {

    @ObservedObject var dataManager: DataManager = DataManager.shared

    @State var selTipoAzienda = 0

    var body: some View {
        VStack {
            companyPhoto
            Text("Company view")
            Form {
                Picker(selection: $selTipoAzienda, label: Text("Tipo Azienda")) {
                    ForEach(0 ..<  self.dataManager.company.tipoAziendaList.count) {
                        Text(self.dataManager.company.tipoAziendaList[$0])
                    }
                }
            }

            Button(action:  {self.dataManager.cambiaTipoAzienda(tipoAzienda: self.dataManager.company.tipoAziendaList[self.selTipoAzienda]) }) {
                Image(systemName: "info.circle.fill")
                    .font(Font.system(size: 28))
                    .padding(.horizontal, 16)
            }
        }
//        .onAppear{
//            self.selTipoAzienda = self.dataManager.company.tipoAziendaList.firstIndex(of: self.dataManager.company.tipoAzienda) ?? 0
//        }
//        .onDisappear{
//            self.dataManager.cambiaTipoAzienda(tipoAzienda: self.dataManager.company.tipoAziendaList[self.selTipoAzienda])
//        }
    }

I think binding and didSet would be the answer but I don't know how they have to be implemented

1 Answers

The provided code is not compilable/testable, so below just shows an approach (see also comments inline)

struct CompanyView: View {

    @ObservedObject var dataManager: DataManager = DataManager.shared
    @State var selTipoAzienda: Int

    init() {
        // set up initial value from persistent data manager
        _selTipoAzienda = State(initialValue: self.dataManager.company.tipoAziendaList.firstIndex(of: self.dataManager.company.tipoAzienda) ?? 0)
    }

    var body: some View {
        // inline proxy binding to intercept Picker changes
        let boundSelTipoAzienda = Binding(get: { self.selTipoAzienda }, set: {
            self.selTipoAzienda = $0

            // store selected value into data manager
            self.dataManager.cambiaTipoAzienda(tipoAzienda: self.dataManager.company.tipoAziendaList[$0])
        })

        return VStack {
            companyPhoto
            Text("Company view")
            Form {
                Picker(selection: boundSelTipoAzienda, label: Text("Tipo Azienda")) {
                    ForEach(0 ..<  self.dataManager.company.tipoAziendaList.count) {
                        Text(self.dataManager.company.tipoAziendaList[$0])
                    }
                }
            }

            Button(action:  {self.dataManager.cambiaTipoAzienda(tipoAzienda: self.dataManager.company.tipoAziendaList[self.selTipoAzienda]) }) {
                Image(systemName: "info.circle.fill")
                    .font(Font.system(size: 28))
                    .padding(.horizontal, 16)
            }
        }
    }
}
Related