Hello!
I am trying to make my own birthdate picker implementation where I want three wheels side-by-side in an HStack. Of course, the values inside these wheels depend on each other, for example, depending on the year, February different number of days, and depending on the month, there are different number of days. I tried making a model for this, but it's returning me the "The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions" error in the init() line. Could you please tell me what's wrong with this?
The picker view:
Section {
HStack {
Picker("Year", selection: birthdateModel.$selectedYear) {
ForEach(birthdateModel.years, id: \.self) {
Text(String($0))
}
}
.pickerStyle(.wheel)
Picker("Month", selection: birthdateModel.$selectedMonth) {
ForEach(birthdateModel.months, id: \.self) {
Text(String($0))
}
}
.pickerStyle(.wheel)
Picker("Day", selection: birthdateModel.$selectedDay) {
ForEach(birthdateModel.days, id: \.self) {
Text(String($0))
}
}
.pickerStyle(.wheel)
}
}
Birthdate model:
class BirthdateModel: Equatable, Hashable {
let monthWith30Days = ["Apr", "Jun", "Sep", "Nov"]
let monthWith31Days = ["Jan", "Mar", "May", "Jul", "Aug", "Oct", "Dec"]
var daysInFeb = 28
let years = 1900...Calendar.current.component(.year, from: Date())
let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
var days = 1...31
var date = 0
let currentDate = Date()
let dateFormatter = DateFormatter()
let monthString = ""
@State var selectedYear: Int = 1900 {
didSet(year) {
if ((year % 4 == 0) && (year / 4 != 0)) {
daysInFeb = 29
}
self.changeDate()
}
}
@State var selectedMonth: String = "Jan" {
didSet(month) {
if monthWith31Days.contains(month) {
days = 1...31
}
else if monthWith30Days.contains(month) {
days = 1...30
}
else {
days = 1...daysInFeb
}
self.changeDate()
}
}
@State var selectedDay: Int = 1 {
didSet(day) {
self.changeDate()
}
}
init() {
self.dateFormatter.dateFormat = "Lll";
self.monthString = self.dateFormatter.string(from: self.currentDate);
self.selectedYear = Calendar.current.component(.year, from: Date())
self.selectedMonth = self.monthString
self.selectedDay = Calendar.current.component(.day, from: Date())
changeDate()
}
func hash(into hasher: inout Hasher) {
hasher.combine(date)
}
static func ==(lhs: BirthdateModel, rhs: BirthdateModel) -> Bool {
return lhs.date == rhs.date
}
func changeDate() {
self.date = (self.selectedYear * 10000) + ((self.months.firstIndex(where: {$0 == self.selectedMonth}) + 1) * 100) + self.selectedDay
}
}