I'm trying to use conditional views but when i change my published variable, the view does not switch to the other, i have to make it reappear, i don't know if it's a SwiftData issue or what but i'm clueless here, it's the first time happening to me
My view :
struct DiaryView: View {
@Environment(\.modelContext) private var modelContext
@Query var macros: [Macros]
@ObservedObject var viewModel = DiaryViewModel()
private func initView() {
viewModel.fetchMacros(macros, viewModel.currentDate)
if viewModel.dailyMacros == nil {
modelContext.insert(Macros())
viewModel.fetchMacros(macros, viewModel.currentDate)
}
}
var body: some View {
VStack {
DailyDateView(date: $viewModel.currentDate)
.onChange(of: viewModel.currentDate) { _ , newValue in
viewModel.fetchMacros(macros, newValue)
}
if viewModel.dailyMacros == nil {
VStack(alignment: .center) {
Spacer()
Text("No data")
.bold()
.font(.title)
Spacer()
}
} else {
HStack {
ProgressCircleView(number1: viewModel.dailyMacros!.carbs, number2: viewModel.totalCarbs, color: Color.brown, size: 80, title: NSLocalizedString("Carbs", comment: ""))
ProgressCircleView(number1: viewModel.dailyMacros!.fat, number2: viewModel.totalFat, color: Color.orange, size: 80, title: NSLocalizedString("Fat", comment: ""))
ProgressCircleView(number1: viewModel.dailyMacros!.proteins, number2: viewModel.totalProteins, color: Color.red, size: 80, title: NSLocalizedString("Proteins", comment: ""))
}
HStack {
ProgressView()
.progressViewStyle(CustomProgressBar(number1: viewModel.dailyMacros!.calories, number2: viewModel.totalCalories, color: Color.purple, width: 300, title: "Calories"))
}
.padding()
HStack {
IncrementButton(number: $viewModel.incrementCarbs, width: 20, color: Color.brown)
IncrementButton(number: $viewModel.incrementFat, width: 20, color: Color.orange)
IncrementButton(number: $viewModel.incrementProteins, width: 20, color: Color.red)
}
HStack {
CustomButtonView(action: {
viewModel.add()
}, label: "Appliquer", color: Color.blue, width: 200, height: 50)
}
}
Spacer()
}
.onAppear {
initView()
}
}
}
My viewModel :
class DiaryViewModel: ObservableObject {
private enum Constants {
static let quickAddMaxNumber: CGFloat = 999
static let quickAddMinimalNumber: CGFloat = 0
}
@Published var incrementCarbs: CGFloat
@Published var incrementProteins: CGFloat
@Published var incrementFat: CGFloat
@Published var dailyMacros: Macros?
var totalCarbs: CGFloat
var totalFat: CGFloat
var totalProteins: CGFloat
var totalCalories: CGFloat
@Published var currentDate: Date
init(incrementCarbs: CGFloat = 0, incrementProteins: CGFloat = 0, incrementFat: CGFloat = 0, dailyMacros: Macros? = nil, currentDate: Date = .now) {
self.incrementCarbs = incrementCarbs
self.incrementProteins = incrementProteins
self.incrementFat = incrementFat
self.dailyMacros = dailyMacros
self.totalCarbs = (UserDefaults.standard.string(forKey: "carbs")?.toCGFloat())!
self.totalFat = (UserDefaults.standard.string(forKey: "fat")?.toCGFloat())!
self.totalProteins = (UserDefaults.standard.string(forKey: "proteins")?.toCGFloat())!
self.totalCalories = (UserDefaults.standard.string(forKey: "calories")?.toCGFloat())!
self.currentDate = currentDate
}
func add() {
guard let macros = dailyMacros else {
return
}
if checkQuickEntrys() {
macros.carbs += incrementCarbs
macros.fat += incrementFat
macros.proteins += incrementProteins
let caloriesFromCarbs = incrementCarbs * 4
let caloriesFromFat = incrementFat * 9
let caloriesFromProteins = incrementProteins * 4
macros.calories += caloriesFromCarbs + caloriesFromFat + caloriesFromProteins
}
resetMacroIncrements()
}
private func resetMacroIncrements() {
incrementCarbs = 0
incrementFat = 0
incrementProteins = 0
}
private func checkQuickEntrys() -> Bool {
guard let macros = dailyMacros,
macros.carbs + incrementCarbs >= Constants.quickAddMinimalNumber,
macros.fat + incrementFat >= Constants.quickAddMinimalNumber,
macros.proteins + incrementProteins >= Constants.quickAddMinimalNumber else {
return false
}
guard let macros = dailyMacros,
macros.carbs < Constants.quickAddMaxNumber,
macros.fat < Constants.quickAddMaxNumber,
macros.proteins < Constants.quickAddMaxNumber else {
return false
}
return true
}
func fetchMacros(_ macros: [Macros], _ date: Date) {
self.dailyMacros = macros.first(where: { Calendar.current.isDate($0.date, equalTo: date, toGranularity: .day) }) ?? nil
}
}
I switched the dailyMacros to the view with a @State property wrapper but nothing changed