Adding an editing event to a UIDatePicker
is something that is required most of the time. For views like UIDatePicker
, we can connect an IBAction
with the event type as value changed
and get a callback for the value changed.
If you are not using xib
or storyboard
but creating the layout programmatically or by using swiftUI
, you can the editing event using a target action that takes three parameters,
- target of
Any
type which is nullable - action of
Selector
type - controlEvents of
UIControl.Event
The code for the same will look like below.
//swift code in viewcontroller
self.datePicker.addTarget(self, action: #selector(onDateValueChanged(_:)), for: .valueChanged)
@objc private func onDateValueChanged(_ datePicker: UIDatePicker) {
//do something here
}
Since the Selector
takes only @objc
functions which can only be defined as a member of the class or an extension of the class, we need to define it at a class level only.
//error
@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes
This way is a bit inefficient as we need to add one function for each UIDatePicker
where we need editing event.
There is a better way where we can add this functionality to each UIDatePicker
without making our class messy.
We can add this to the UIDatePicker
extension itself which will be a very clean approach and will make our life super easy.
First, add a function as an extension to UIDatePicker
class which takes a function as a parameter with 0 params and Void return type.
Since this function will be our callback function, add @escaping
to the function passed as the parameter.
//MARK: - UIDatePicker Extension
extension UIDatePicker {
func setOnDateChangeListener(onDateChanged :@escaping () -> Void){
}
}
Now add an action to the UIDatePicker
object in the same function which takes two parameters.
- action of
UIAction
type - controlEvents of
UIControl.Event
There are multiple constructors for UIAction
but will take the most simple one where it takes one parameter ie handler of UIActionHandler
type. Rest all params either have a default value or are of nullable types.
And, we can call our callback function in the handler callback.
//MARK: - UIDatePicker Extension
@available(iOS 14.0, *)
extension UIDatePicker {
func setOnDateChangeListener(onDateChanged :@escaping () -> Void){
self.addAction(UIAction(){ action in
onDateChanged()
}, for: .valueChanged)
}
}
This took care of all the boilerplate code and added a simple public function to each UIDatePicker
for text change event.
To call this function, simply call setOnDateChangeListener
to any UIDatePicker
in your ViewController.
//swift code in view viewcontroller
self.datePicker.setOnDateChangeListener {
print("date changed")
}
No extra function required in ViewController and it will be very clean.
But keep in mind, the function addAction is only available in iOS 14 or above
If your codebase still supports below iOS 14, then you need to go with the addTarget
and Selector
function only.