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