ios - example - uidatepicker swift 4
UIDatePicker error? UIControlEventValueChanged después de alcanzar el mínimo interno (7)
Para Swift 3:
DispatchQueue.main.async(execute: {
yourPicker.countDownDuration = TimeInterval()
})
Me he encontrado con un efecto extraño que seguramente parece un error en iOS7, pero a menudo en el pasado, cuando pensé que había encontrado un error en las API de Apple, resultó ser mi propio malentendido.
Tengo un UIDatePicker con datePickerMode = UIDatePickerModeCountDownTimer y minuteInterval = 5. Inicializo la duración a 1 hora, y la presento al usuario, donde aparece como un selector de dos columnas con horas y minutos. (Hasta ahora tan bueno.)
El usuario está pensando en "20 minutos" y, por lo tanto, desplaza la columna Hora a 0. En este punto, el selector lee 0 horas y 0 minutos, y iOS7 no está bien con eso, por lo que automáticamente mueve la rueda de minutos a 5. Mi UIControlEventValueChanged el controlador se invoca y la cuentaDownDuration lee 5 minutos. (Sigue bien.)
Ahora el usuario agarra la rueda de los minutos y la arrastra hasta 20. Y ... no se llama a mi controlador UIControlEventValueChanged. (Malo.)
Si tengo algún otro evento en la interfaz de usuario, compruebe el selector de fecha en este momento, veo que la cuenta de ajuste de reducción de tiempo está configurada en 20. Pero no tenía forma de saber que el usuario la cambió, en el momento en que se cambió. Esto es muy repetible: siempre ocurre en el primer cambio DESPUÉS de que el selector se niega a configurarse en 0 (avanzando a sí mismo a 5 minutos).
Tenga en cuenta que esto está en iOS7; no ocurre en iOS6 (quizás porque el selector está perfectamente contenido para configurarse en 0 minutos).
Entonces ... ¿me estoy perdiendo algo aquí? ¿O es este un error genuino en iOS7? Y en este último caso, ¿alguien conoce mejor una solución alternativa que tener algún temporizador que verifique periódicamente el intervalo actual?
Seguía teniendo este problema en la versión 7.1, pero agregando lo siguiente al controlador UIControlEventValueChanged lo solucioné para mí.
// Value Changed Event is not firing if minimum value hit
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self.myDatePicker setCountDownDuration: self.myDatePicker.countDownDuration];
});
Si alguien sigue teniendo problemas con el selector de fechas ... Estoy usando Swift / iOS 8 / Xcode 6.3
Así que resuelve el problema que no debes usar.
picker.countDownDuration = NSTimeInterval
en su lugar, usa setDate
picker.setDate(NSDate, animated: true)
funciona directamente en viewDidLoad()
, no es necesario usar `colas
Si alguien sigue teniendo problemas con el selector de fechas ... Estoy usando Swift / iOS 8 / Xcode 6.3
Para resolver el problema, no debe utilizar picker.countDownDuration = NSTimeInterval
. Utilice .setDate(NSDate, animated: true)
.
funciona directamente en viewDidLoad()
, no necesita usar queues
El fragmento completo:
override func viewDidLoad() {
super.viewDidLoad()
picker.setDate(setDateFromSeconds(seconds), animated: true)
}
func setDateFromSeconds(seconds: Double) -> (NSDate) {
let intSeconds = Int(seconds)
let minutes = (intSeconds / 60) % 60
let hours = intSeconds / 3600
let dateString = NSString(format: "%0.2d:%0.2d", hours, minutes)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "hh:mm"
return dateFormatter.dateFromString(dateString as String) as NSDate!
}
Swift 4
@IBOutlet weak var fromPickerView: UIDatePicker!
@objc func toPickerViewDateChanged() {
fromPickerView.minimumDate = toPickerView.date
}
override func viewDidLoad() {
super.viewDidLoad()
toPickerView.backgroundColor = UIColor.white
toPickerView.tintColor = .black
toPickerView.maximumDate = Date()
toPickerView.addTarget(self, action:
#selector(toPickerViewDateChanged), for: UIControlEvents.valueChanged)
También puedo confirmar que el UIDatePicker de iOS 7.0.3 tiene un error cuando se usa en el modo UIDatePickerModeCountDownTimer. El selector no dispara la acción objetivo asociada con el evento UIControlEventValueChanged la primera vez que el usuario cambia el valor desplazando las ruedas. Funciona bien para los cambios posteriores.
A continuación se muestra una solución eficiente. Simplemente encierre el código que establece el valor inicial de countDownDuration en un bloque de envío al bucle principal. Su método de acción objetivo disparará cada vez que las ruedas giren a un nuevo valor. Este enfoque casi no tiene gastos generales y funciona bastante bien en un iPhone 4 y iPad 4.
dispatch_async(dispatch_get_main_queue(), ^{
self.myDatePicker.countDownDuration = (NSTimeInterval) aNewDuration ;
});
Ya que ninguna respuesta ha sido aceptada todavía. La solución más simple que me funcionó en swift 3 es simplemente hacer
datePicker.countDownDuration = segundos
en viewDidAppear en lugar de viewDidLoad