Hello:
I have a view that uses an environment variable containing an array of class objects. Each of these objects has a boolean property called 'Cached' that I need to toggle to allow the user to show either Image A or B on a button. Here is my code:
import UIKit
import SwiftUI
import Combine
class People : ObservableObject, Decodable {
@Published var list: [Person]
init() {
self.list = JSONServices().getData()
}
}
class Person: ObservableObject, Identifiable {
let id = UUID()
let name: String
let bio: String
let category: Category
let image: String
@Published var cached: Bool = false
@Published var metadata: ForecastMetaData?
init(name: String, bio: String, category: Category, image: String, lat: Double, lon: Double, cached: Bool) {
self.name = name
self.bio = bio
self.category = category
self.image = image
self.cached = cached
self.metadata = Servive.getData()
}
}
struct ContentView: View {
@State var searchText: String = ""
@State var searchCategory: Int = 0
// Filter the person per the search box
var filteredPeople: [Person] {
if !self.searchText.isEmpty && self.searchCategory == 0{
return Employees.list.filter { $0.name.lowercased().prefix(searchText.count).contains(searchText.lowercased()) }
} else if !self.searchText.isEmpty && self.searchCategory != 0 {
return Employees.list.filter { $0.name.lowercased().prefix(searchText.count).contains(searchText.lowercased()) && $0.category == searchCategory }
} else if self.searchText.isEmpty && self.searchCategory != 0 {
return Employees.list.filter { $0.category == searchCategory }
} else {
return Employees.list
}
}
// get the information from the environment object
@EnvironmentObject var Employees: People
var body: some View {
NavigationView {
List {
CustomSearchBar(searchText: $searchText, searchCategory: $searchCategory)
ForEach(filteredPeople) { employee in
ZStack {
NavigationLink(destination: DisplayEmployeeInfo(id: employee.id)) {
ListEmployees(employee:employee)
}
}
.swipeActions(edge: .leading, content: {
Button {
employee.cached.toggle() // THIS IS WHAT IS NOT WORKING
} label: {
Label("Cache", systemImage: !employee.cached ? "square.and.arrow.down" : "trash")
}
.tint(!employee.cached ? .green : .red)
})
}
}
.navigationBarTitle(Text("My Employees"),displayMode: .large)
}
}
}
When the user clicks the button the image on the label does not change from "square.and.arrow.down" to "trash" (or viceversa) even though the property's value has in fact changed. I have checked this by attaching a "didSet" event on the property to output to the console once the property has changed. I am curious to know what my mistake is, why is the actual image not updating if the porperty has in fact changed values and it is set to advertise its changes as a published property of an observable object?
I should note that I can get this to work if I change the Person class to be a Struct instead. But I have to say I don't know why that matters if with it being a class I am making direct changes to the correct object's property. Any help would be appreciated!