From https://stackoverflow.com/a/58664469/15445779 I have the DatePicker. I tried to edit it so, that I can change the months if the DatePicker is at the ends of the interval so, that only the months inside the interval gets displayed?
struct PickerView: UIViewRepresentable {
var data: [[String]]
@Binding var selections: [Int]
//makeCoordinator()
func makeCoordinator() -> PickerView.Coordinator {
Coordinator(self)
}
//makeUIView(context:)
func makeUIView(context: UIViewRepresentableContext<PickerView>) -> UIPickerView {
let picker = UIPickerView(frame: .zero)
picker.dataSource = context.coordinator
picker.delegate = context.coordinator
return picker
}
//updateUIView(_:context:)
func updateUIView(_ view: UIPickerView, context: UIViewRepresentableContext<PickerView>) {
for i in 0...(self.selections.count - 1) {
view.selectRow(self.selections[i], inComponent: i, animated: false)
}
context.coordinator.parent = self // fix
}
class Coordinator: NSObject, UIPickerViewDataSource, UIPickerViewDelegate {
var parent: PickerView
//init(_:)
init(_ pickerView: PickerView) {
self.parent = pickerView
}
//numberOfComponents(in:)
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return self.parent.data.count
}
//pickerView(_:numberOfRowsInComponent:)
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.parent.data[component].count
}
//pickerView(_:titleForRow:forComponent:)
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.parent.data[component][row]
}
//pickerView(_:didSelectRow:inComponent:)
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.parent.selections[component] = row
}
}
}
My SwiftUI View: My idea is to change the data[0] Array to only the months that are inside of the interval. My question is how can I make that the picker displays only these months?
struct DatePicker_Interval:View{
@State var data: [[String]]
@State private var selections: [Int] = [0,0]
@Environment(\.calendar) var calendar
let interval: DateInterval
init(interval: DateInterval) {
self._data = State(initialValue: [
Array(Calendar.current.component(.year, from: interval.start)...Calendar.current.component(.year,from: interval.end)).map { "\($0)" },
Array(1...12).map { "\(DateFormatter().monthSymbols[$0-1])" },
])
self.interval = interval
}
var body: some View{
VStack{
PickerView(data: data, selections: $selections)
.onChange(of: selections[0], perform: { _ in
if(data[0][selections[0]] == String(Calendar.current.component(.year, from: interval.start))){
print(interval.start)
print(calendar.component(.month, from: interval.start))
print(Array(calendar.component(.month, from: interval.start)...12).map { "\(DateFormatter().monthSymbols[$0-1])" })
data[1] = Array(calendar.component(.month, from: interval.start)...12).map { "\(DateFormatter().monthSymbols[$0-1])" }
}else if(data[0][selections[0]] == String(Calendar.current.component(.year, from: interval.end))){
print(interval.end)
print(calendar.component(.month, from: interval.end))
print(Array(1...calendar.component(.month, from: interval.end)).map { "\(DateFormatter().monthSymbols[$0-1])" })
data[1] = Array(1...calendar.component(.month, from: interval.end)).map { "\(DateFormatter().monthSymbols[$0-1])" }
}
})
HStack{
Text("selection[0]: \(selections[0])")
Text("selection[1]: \(selections[1])")
}
Text("Intervall: Start - \(interval.start.description)")
Text("Intervall: End - \(interval.end.description)")
}
}
}
Content View
struct ContentView: View {
@Environment(\.calendar) var calendar
private var testInterval: DateInterval {
let comp = DateComponents(year: 2001, month: 5)
let comp2 = DateComponents(year: 2002, month: 8)
return DateInterval(start: calendar.date(from: comp) ?? Date(), end: calendar.date(from: comp2) ?? Date())
}
var body: some View {
DatePicker_Interval(interval: testInterval)
}
}