I am trying to make a calendar app that can be used on iPhone. I am using SwiftUI for the app and FirebaseFirestore
as my database.
What I am trying to do is to make a document in Firestore
inside a collection(User), and I want the name of the document to be the date that the user picked using datepicker. I have searched up about turning date into String
, but when I apply it on @State
variable, it gives an alert. Is there any way to solve this problem?
Below is the code:
import SwiftUI
struct SwiftUIView: View {
@State var date = Date()
var picked = dateToString(date: date, format: "YYYY MM dd")
var body: some View {
DatePicker(
"Datepicker",
selection: $date
)
.datePickerStyle(.graphical)
}
func dateToString(date: Date, format: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
return dateFormatter.string(from: date)
}
}
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView()
}
}
On the line with var picked
, two errors occur:
-
Cannot use instance member 'date' within property initializer; property initializers run before 'self' is available
-
Cannot use instance member 'dateToString' within property initializer; property initializers run before 'self' is available
CodePudding user response:
Replace picked
with that:
var picked: String {
dateToString(date: date, format: "yyyy MM dd")
}
It should be a computed variable.
CodePudding user response:
You can't use any variables of the view before self is initialized. This means that you can only use the variables when self is available. As this cannot be the case in this situation you should go with something like this:
struct SwiftUIView: View {
@State var date = Date()
@State var picked : String = ""
var body: some View {
DatePicker(
"Datepicker",
selection: $date
)
.datePickerStyle(.graphical)
}
// This code will be executed as the view appears
.onAppear {
self.picked = self.dateToString(date: date, format: "YYYY MM dd")
}
// This code will be executed if the date the user can pick changes
// If the user changes the date the picked date will also be changed
.onChange(of: self.date) { newDate in
self.picked = self.dateToString(date: newDate, format: "YYYY MM dd")
}
func dateToString(date: Date, format: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
return dateFormatter.string(from: date)
}
}
The onChangeOf
will make sure that your Date as a String is always up to date with the Date of the Datepicker.
See documentation for .onAppear
: https://developer.apple.com/documentation/swiftui/view/onAppear(perform:)
See documentation for .onChangeOf
: https://developer.apple.com/documentation/swiftui/view/onchange(of:perform:)
To just set the var picked you have to a use a computed variable like this:
var picked: String {
dateToString(date: date, format: "YYYY MM dd")
}