2

I'm trying to fetch some data on a network call when a user selects a time from DatePicker.

I originally tested using .onChange but this fires every time that changes, and not on the final tap off.

DatePicker("Title", selection: $currentDate, displayedComponents: .hourAndMinute)
  .onChange(of: $currentDate) { value in
    print(value)
  }

I also tried using the didset{} but that also fired on every change too.

@Published var currentDate: Date = Date() {
  didSet { print(currentDate) }
}

What I want to do is once the user selects a time, I fire off some functions. I wanted to not do it every cycle in the wheel.

Is there a way to do this in SwiftUI or UIKit importing into SwiftUI?

Please see attached of what I'm looking at:

enter image description here

markb
  • 1,100
  • 1
  • 15
  • 40
  • `.onChange` is a very reasonable way to go. The problem you are having is that you need to debounce the input from the picker. See [this solution](https://stackoverflow.com/a/66165075/7129318). It is for a text field, but it is exactly the same problem: how to wait until the user is done before implementing a function call. – Yrb Feb 14 '22 at 02:06

1 Answers1

0

You could try rolling your own DatePickerView, such as this approach:

struct ContentView: View {
    @State private var birthdate = Date()

    var body: some View {
            DatePickerView(date: $birthdate)
    }
}

struct DatePickerView: View {
    @Binding var date: Date
    @State var hasChanged = false
    
    var body: some View {
        ZStack {
            Color.white.opacity(0.01).ignoresSafeArea()
                .onTapGesture {
                    if hasChanged {
                        print("---> do a network call now with: \(date)")
                        hasChanged = false
                    }
                }
            DatePicker("Birth Date", selection: $date, displayedComponents: .hourAndMinute)
                .pickerStyle(.wheel)
                .onChange(of: date) { val in
                    hasChanged = true
                }
        }
    }
}
  • Didn't think of doing it this way - fairly neat for a quick solution. I will add this in after I roll out, but was using the Timer to delay for a little bit – markb Feb 15 '22 at 04:37