In the following code I would expect my ContentView to update after invoking the "Update" swipeAction which in turn enables updating the selected country population value. The correct value is returned but it does not trigger the ContentView to update the selected country's population value.
import SwiftUI
class Country: ObservableObject {
var id = UUID()
@Published var code: String
@Published var population: Int
init(code: String, population: Int) {
self.code = code
self.population = population
}
}
typealias Countries = [Country]
struct ContentView: View {
@State var showPopover = false
@State var selectedCountry: Country = Country(code: "??", population: 0)
@State var newValue: Int = 0
@State var countries: Countries = Countries()
var body: some View {
List (countries, id: \.id) { country in
HStack {Spacer(); Text(country.code); Spacer(); Text("\(country.population)"); Spacer()
}.font(.title)
.swipeActions(content: {
Button { selectedCountry = country; showPopover = true } label: { Text("Update") }
})
}.popover(isPresented: $showPopover) {
PopoverView(country: $selectedCountry)
}.onAppear {
if countries.isEmpty {
countries.append(contentsOf:
[Country(code: "AU", population: 26000000),
Country(code: "US", population: 332000000),
Country(code: "UK", population: 67000000)
])
}
}
}
}
struct PopoverView: View {
@Environment(\.presentationMode) var presentationMode
@Binding var country: Country
@State var value = "???"
var body: some View {
HStack {
Spacer()
Text(country.code)
TextField(country.code, text: $value)
Button {
if let intValue = Int(value) { country.population = intValue }
print("New population: \(country.population)")
presentationMode.wrappedValue.dismiss()
}
label: { Text("DONE")}
Spacer()
}.onAppear {
value = String(country.population)
}
}
}
I've tried everything suggested in a number of online articles but nothing seems to cause the ContentView to update the selected population
I've digged into your issue and found a solution. Your solution doesn't work because you are editing the selectedCountry variable (and never really displaying it) and not the collection values themeselves. First, I needed to refactor your model like this:
Storing your countries into an ObservableObject class, I also made your Country class Identifiable since it already had an ID, so when looping through it we would not have any issues.
Then I've edited your Popover view to take in a function:
I've called that function once the edit action was complete. I've then used your selectedCountry to edit the actual collection values stored in the countryContainer StateObject like so:
This solution is maybe not the best, and you can work out way to improve it, but I just wanted to point you in the right direction. I hope I could help you and my explaination was clear. Let me know!