I don't know how to read a property that is in a struct from a class that is an Observable Object.
Context:
I'm trying to build an app which consists of 2 views:
- a custom calendar;
- a popup with a header 'Daily Joke', date formatted as 'MM-dd-yyyy' and a joke text that is fetched from Firebase using id. When the user clicks on a date in the calendar, the popup appears and shows the joke for a selected date.
The problem is that the 'currentDate' property (holds the value of the selected date) that I reference in the ObservableObject of the 'getJoke' class won't update when the user selects a different date. It always fetches the joke on today's date and not on the one the user has selected.
Here is the code of:
- the custom calendar (selected date is held in the property 'currentDate')
import SwiftUI
import grpc
struct CustomDatePicker: View {
@State var currentDate: Date
@State var dailyJokePopUp = false
//some code here
// When the user selects the date, currentDate property changes to the selected date
.onTapGesture {
currentDate = value.date
}
// Getting selected day for displaying in dailyJokePopUp
func getCurrentDay()->String{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy"
let date = dateFormatter.string(from: currentDate)
return date
}
- the class which is an @ObservableObject (I use it to add a listener to the Firebase to fetch the joke text by its id. Here I need to read 'currentDate' which is originally declared and changed in CustomDatePicker. I need to do it to check if 'currentDate' matches the id in Firebase (that way the joke text is fetched from Firebase on the selected date)).
class getJoke : ObservableObject {
@Published var data = [JokeX]()
@Published var noData = false
@Published var currentDate = Date()
//some code here including adding SnapShotListener
let callCDP = CustomDatePicker(currentDate: currentDate).getCurrentDay()
if id == callCDP {
self.data.append(joke_text_imported)}
}
}
}
}
- the popup (I call the result of the @ObservableObject to get the display the text fetched from Firebase)
import SwiftUI
struct dailyJokePopUp: View {
@Binding var show: Bool
@ObservedObject var Jokes = getJoke()
var currentDate: Date = Date()
//some code here
ForEach(self.Jokes.data){i in
Text(i.joke_text)
}
//some code here
}
I can suspect something is wrong with how I declare properties. I've tried various wrappers (@Binding, @StateObject), but I got confused and it didn't work. Hope someone can be kind enough to help me solve the problem.
CodePudding user response:
ViewModel
class getJoke: ObservableObject {
@Published var currentDate = Date()
}
View that can change passing data
struct CustomDatePicker: View {
@Binding var currentDate: Date
var body: some View{
VStack {
DatePicker(selection: $currentDate, displayedComponents: .date){
Text("Select your date")
}
.datePickerStyle(.compact)
}
}
}
And put everything together
struct ContentView: View {
@StateObject var vm = getJoke()
var body: some View {
VStack(spacing: 40) {
CustomDatePicker(currentDate: $vm.currentDate)
Button {
print(vm.currentDate)
} label: {
Text("Show selected date")
}
}
}
}