UIDate Picker valuechanged no actualiza el primer giro, pero hace cada giro después … iOS

Tengo un selector de UIDate embedded en un TableViewCell estático y actualmente deshabilité la mayor parte del código excepto el código responsable del selector de date.

Estoy usando el datepicker como un timer de count regresiva

Entonces, esto es todo, excepto algunas tomas y vars habituales:

override func viewDidLoad() { super.viewDidLoad() // tfName.delegate = self // tfDescription.delegate = self // datePicker.countDownDuration = 60 // pickerValueChanged(self) } @IBAction func pickerValueChanged(sender: AnyObject) { seconds = Int(datePicker.countDownDuration) hours = seconds / 3600 if hours == 0{ minutes = seconds / 60 } else{ minutes = seconds % 3600 / 60 } labelDuration.text = "\(hours) hours \(minutes) minutes" } 

La primera vez que cambio el valor del selector, la function de cambio de valor no se dispara en absoluto, pero los giros después de hacerlo sin falla.

Intenté llamarlo en viewDidLoad , con pickerValueChanged(self) y eso funciona, pero no resuelve el problema. También comenté cada línea de código en la function viewDidLoad y viewDidLoad pero todavía no disparó el primer giro …

¡Gracias por tu time!

Actualización: imágenes añadidas

Después del primer giro, pickerValueChanged no recibe el llamado: Primera vuelta

A partir del segundo giro y más allá, se llama al evento y se actualiza la label: Segunda vuelta

Intentó:

Ejecutando: datePicker.setDate(NSDate(), animated: true en viewDidLoad() resuelve el problema de que el evento no se viewDidLoad() en el primer giro, pero esto establece el estado inicial del datepicker en la hora actual. Estoy usando este control para establecer una duración en un evento, quiero dejar que comience en 0 hora y 1 minuto. Esto se puede hacer con datePicker.countDownDuration = 60 pero después de esto, el problema principal vuelve a aparecer. Entonces, una solución podría configurar el DatePicker con un NSDate de 1 minuto, pero ¿cómo hacer esto?

Solución:

 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) 

Apareció la siguiente solución para inicializar el componente datePicker (en modo timer de count regresiva) con 0 horas y 1 minuto y responde directamente en el primer giro. Dado que esto parece ser un error y es muy frustrante si quieres que una label de text actualice su valor cuando se cambia la date y no lo hace a la primera vez:

 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) 

El componente timeZone no es realmente necesario para que esto funcione para mi implementación.

Creo que deberías intentar implementar este delegado en su lugar

 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component 

Parece que tiene algo que ver con el parámetro animado. Solo necesitas esta línea:

 datePicker.setDate(date, animated: true) 

Hace un time encontré otro problema que de alguna manera se parece a este. Se trataba de presentar un controller de vista desde dentro de tableView:didSelectRowAtIndexPath: y el problema era que tomaba mucho time para que el nuevo controller apareciera realmente. Una de las soluciones provisionales resultó ser el uso de dispatch_async en la queue principal. Lo mismo funcionó para mí en este caso.

En mi viewDidLoad , viewDidLoad asíncronamente el código de configuration del selector en la queue principal y, en mi caso, comenzó a responder al evento valueChanged incluso en la primera selección:

 DispatchQueue.main.async { self.pickerView.datePickerMode = .countDownTimer self.pickerView.minuteInterval = 5 self.pickerView.countDownDuration = 15 } 

No sé si obtuve su problema, pero el datepicker funciona con el patrón de acción de destino y desencadena este mecanismo cuando cambia un valor.
Entonces, si el problema es el primer valor mostrado, debe inicializar su variable tomándolo como el valor "pnetworkingeterminado".

Aquí se actualiza y simplifica la solución de @ Henk-Martijn para Swift 3 :

 let calendar = Calendar(identifier: .gregorian) let date = DateComponents(calendar: calendar, hour: 1, minute: 30).date! datePicker.setDate(date, animated: true) 

Use el código anterior en lugar de algo como:

 datePicker.countDownDuration = 5_400