Uidatepicker Bug? Uicontroleventvaluechanged After Hitting Minimum Internal

Date Picker with UIControlEvents.valueChanged doesn't work on the first value change event

Strange. This appears to be a bug in date pickers that are set to UIDatePickerMode.countDownTimer mode.

You can get around most of the fail cases by implementing the UITextFieldDelegate method textFieldShouldBeginEditing(_:) and setting the picker's value after a short delay. Here is the code from my test project. (In my project the time interval field is called optionalTimeField, and the time interval value is an optional called optionalTime. You'd need to change it to fit your code:

EDIT:

See new function textField(_:,shouldChangeCharactersInRange:,replacementString:) below

extension ViewController: UITextFieldDelegate {

//Add this function to prevent keyboard editing
func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
return false
}

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField === optionalTimeField {
//Set the time interval of the date picker after a short delay
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.datePickerView.countDownDuration = self.optionalTime ?? 60
}

}
return true
}
}

I would suggest filing a bug report with Apple bug reporter. Based on the thread @Santosh linked, it looks like this bug has been in the UIDatePicker since iOS 7, which is bad.

One bug that I don't see a work-around for is that if you try to select a time interval of 0 hours, 0 minutes, it switches to 1 minute, and after that, the next time interval you select does not trigger the value changed method.

There are various strange things about the interval date picker, like the fact that you can't specify it to choose seconds. If it's important enough, you might want to create your own time interval picker based on a generic UIPickerView. It shouldn't be that hard. (Especially if you don't need to worry about localization to multiple locales that use different time formats.) You'd just create a picker view with spinners for hour, minute, and (optionally) seconds, populate it with your legal values, and away you'd go. You could set it up to have optional minimum and maximum interval values.

UIDate Picker valuechanged does not update the first spin, but does every spin after.. iOS

I came up the following solution to initialize the datePicker component (in countdown timer mode) with 0 hours and 1 minute and it responds directly at the first spin. Since this appears to be a bug and is very frustrating if you want a textlabel to update its value when the datePicker is changed and it does not at the first go:

var dateComp : NSDateComponents = NSDateComponents()
dateComp.hour = 0
dateComp.minute = 1
dateComp.timeZone = NSTimeZone.systemTimeZone()
var calendar : NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)!
var date : NSDate = calendar.dateFromComponents(dateComp)!

datePicker.setDate(date, animated: true)

The timeZone component is not really needed for this to work for my implementation.

UIDatePicker valueChanged as wheels spin?

This is an extreme workaround, but...

If you use a UIPickerView instead of a UIDatePicker (which, granted, would entail re-implementing most of the DatePicker), you can detect the wheel spinning in the pickerView:viewForRow:forComponent:reusingView: delegate method. If there are more rows than can be displayed at once, this will be called every time the wheel moves.



Related Topics



Leave a reply



Submit