Premise
I have a MultiDatePicker bounded to a closed range of the current month. In addition, I have a datePicker representing a "Start Date" that is the current day. I want the Day of the Month from "Start Date" to be pre-selected in the MultiDatePicker.
Example Code
import SwiftUI
import SwiftData
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@State private var days: Set<DateComponents> = []
var body: some View {
VStack {
Text("Selected Days")
let dayArray = Array(days)
ForEach(dayArray, id: \.self) { day in
Text(Calendar.current.date(from: day)?.formatted(date: .complete, time: .complete) ?? "")
}
MultiDatePicker("", selection: $days)
}
}
}
#Preview {
ContentView()
.modelContainer(for: Item.self, inMemory: true)
}
Attempted Solution
I have attempted to add a DateComponent in the initial value for days, like this
@State private var days: Set<DateComponents> = [DateComponents(year: 2025, month: 11, day: 19)]
(In my fully-implemented version, I use values from "Start Date" and the current Date. From testing, hard-coding the date did not seem to affect my outcome. They are hard-coded here for simplicity)
Problem: For some reason, I am unable to remove this default option from the picker. When de-selecting the current date from the picker,
- The date never leaves the list of selected dates
- The date re-appears when closing the picker and re-opening it
- The de-selection doesn't call a .onChange(of: days) {...}
Observation: In my fully implemented version of this, I've found I'm able to double-select the pre-selected date. I do this by first de-selecting (which doesn't remove it), then re-selecting it (which adds the second instance).
This gave me the suspicion that, at times, I'm storing 2 instances of DateComponents with the same date values, but different time values.
After printing all DateComponents stored, I observed that the two instances of DateComponent sharing that Day of the Month are identical in date and time down to the second.
Calendar.Componentas the date picker is using. This set is[.calendar, .era, .year, .month, .day]- see MultiDatePicker onChange not called if selection is set programmatically for details.