3

I have a Picker that updates a @Binding value, that is linked to the original @State value. The problem is that it gets updated only the first time I change it, and then it always remains like that. Not only in the sheet, but also in the ContentView, which is the original view in which the @State variable is declared. Here's a video showing the problem, and here's the code:

ContentView:

struct ContentView: View {
    
    @State var cityForTheView = lisbon
    @State var showCitySelection = false

    var body: some View {
        VStack {
            //View
        }
        .sheet(isPresented: $showCitySelection) {
            MapView(cityFromCV: $cityForTheView)
        }
    }
}

MapView:

struct MapView: View {
    
    @Environment(\.presentationMode) var presentationMode
    @Binding var cityFromCV : CityModel
    
    @State var availableCities = [String]()
    @State var selectedCity = "Lisbon"
    
    var body: some View {
        NavigationView {
            ZStack {
            VStack {
                Form {
                    HStack {
                        Text("Select a city:")
                        Spacer()
                        Picker("", selection: $selectedCity) {
                            ForEach(availableCities, id: \.self) {
                                            Text($0)
                                        }
                                    }
                        .accentColor(.purple)

                    }
                    .pickerStyle(MenuPickerStyle())
                    

                    Section {
                        Text("Current city: \(cityFromCV.cityName)")
                    }
                }
            }
        }
        }
        .interactiveDismissDisabled()
        .onAppear {
            availableCities = []
            for ct in cities {
                availableCities.append(ct.cityName)
            }
        }
        .onChange(of: selectedCity) { newv in
            self.cityFromCV = cities.first(where: { $0.cityName == newv })!
        }
    }
}

CityModel:

class CityModel : Identifiable, Equatable, ObservableObject, Comparable {
    
    var id = UUID()
    var cityName : String
    var country : String
    var imageName : String

    init(cityName: String, country: String, imageName : String) {
        self.cityName = cityName
        self.country = country
        self.imageName = imageName
    }
    
    static func == (lhs: CityModel, rhs: CityModel) -> Bool {
        true
    }
    
    static func < (lhs: CityModel, rhs: CityModel) -> Bool {
        true
    }

}
  
var cities = [
    lisbon,
    CityModel(cityName: "Madrid", country: "Spain", imageName: "Madrid"),
    CityModel(cityName: "Barcelona", country: "Spain", imageName: "Barcelona"),
    CityModel(cityName: "Paris", country: "France", imageName: "Paris")
]

var lisbon = CityModel(cityName: "Lisbon", country: "Portugal", imageName: "Lisbon")

What am I doing wrong?

Pandruz
  • 345
  • 5
  • 18
  • This https://stackoverflow.com/a/64554083/12299030, or this https://stackoverflow.com/a/63089069/12299030 – Asperi Jun 17 '22 at 09:36
  • But this doesn't update the original value in the ContentView, if I close the sheet, the value in the ContentView is still like after the first update, but it doesn't change anymore no matter how many times I tap or close/open the sheet – Pandruz Jun 17 '22 at 09:41
  • @Asperi it's not that I can't access the latest value, it's that the actual value doesn't change – Pandruz Jun 17 '22 at 09:56
  • 1
    Make CityModel struct – Asperi Jun 17 '22 at 10:03

1 Answers1

1

The problem are:

at line 35: you use selectedCity to store the selected data from your picker.

 Picker("", selection: $selectedCity) {

then at your line 46: you use cityFromCV.cityName to display the data which will always show the wrong data because you store your selected data in the variable selectedCity.

 Section {
  Text("Current city: \(cityFromCV.cityName)")
 }

Solution: Just change from cityFromCV.cityName to selectedCity.

Steven-Carrot
  • 2,368
  • 2
  • 12
  • 37