UIDate Picker valuechanged не обновляет первое вращение, но делает каждый поворот после.. iOS

У меня есть UIDate Picker, встроенный в статический TableViewCell, и на данный момент я отключил большую часть кода, кроме кода, ответственного за выбор даты.

Я использую Date Picker в качестве таймера обратного отсчета

Итак, это все, кроме некоторых обычных выходов и vars:

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"
}

В первый раз, когда я изменяю значение Picker, функция изменения значения не срабатывает вообще, но спины после нее без сбоев.

Я попытался вызвать его в viewDidLoad, с pickerValueChanged(self), и это работает, но не решает проблему. Кроме того, я прокомментировал каждую строку кода в функции pickerValueChanged и viewDidLoad, но он все еще не запускал первое вращение.

Спасибо за ваше время!

Обновление: добавленные фотографии

После первого вращения pickerValueChanged не вызывается: First spin

От второго вращения и дальше, событие вызывается и обновляется метка: Second spin

Пробовал:

Выполнение:   datePicker.setDate(NSDate(), animated: true в viewDidLoad() решает проблему, что событие не вызывается при первом вращении, но это устанавливает начальное состояние Date Picker в текущее время. Поскольку я использую этот элемент управления для установки продолжительности события, я хочу, чтобы он начинался с 0 часов и 1 минуты. Это можно сделать с помощью datePicker.countDownDuration = 60, но после этого основная проблема снова возвращается. Таким образом, решение может устанавливать DatePicker с NSDate на 1 минуту, но как это сделать?

Решение:

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)

Ответ 1

Я придумал следующее решение для инициализации компонента datePicker (в режиме таймера обратного отсчета) с 0 часов и 1 минутой, и он реагирует непосредственно при первом вращении. Поскольку это кажется ошибкой и очень неприятно, если вы хотите, чтобы текстовая метка обновляла свое значение, когда datePicker изменен, и он не с первого раза:

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)

Компонент timeZone действительно не нужен, чтобы это работало для моей реализации.

Ответ 2

Здесь решение @Henk-Martijn обновлено и упрощено для Swift 3:

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

Используйте приведенный выше код вместо следующего:

datePicker.countDownDuration = 5_400

Ответ 3

Я думаю, вы должны попробовать реализовать этот делегат вместо

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

Ответ 4

Кажется, что-то связано с анимированным параметром. Вам просто нужна эта строка:

datePicker.setDate(date, animated: true)

Ответ 5

Время от времени я нашел еще одну проблему, которая как-то напоминает это. Речь шла о представлении контроллера вида из tableView:didSelectRowAtIndexPath:, и проблема заключалась в том, что для запуска нового контроллера было достаточно времени. Одним из обходных решений оказалось использование dispatch_async в главной очереди. В этом случае я работал в этом случае.

В моем viewDidLoad я асинхронно отправил код настройки выбора в основной очереди и, в моем случае, он начал отвечать на событие valueChanged даже на первый выбор:

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

Ответ 6

Я не знаю, была ли у меня проблема, но функция выбора даты работает с использованием шаблона целевого действия и запускает этот механизм при изменении значения.
Поэтому, если проблема - это самое первое показанное значение, вы должны инициализировать свою переменную, принимая ее как значение по умолчанию.