Ошибка UIDatePicker? UIControlEventValueChanged после достижения минимального внутреннего
Я столкнулся с странным эффектом, который наверняка выглядит как ошибка в iOS7, но часто в прошлом, когда я думал, что нашел ошибку в API Apple, это оказалось моим собственным недоразумением.
У меня есть UIDatePicker с datePickerMode = UIDatePickerModeCountDownTimer и minuteInterval = 5. Я инициализирую продолжительность до 1 часа и представляю ее пользователю, где он отображается как двухстоечный сборщик с часами и минутами. (Все идет нормально.)
Пользователь думает "20 минут" и поэтому прокручивает столбец "Час" до 0. В этот момент сборщик читает 0 часов и 0 минут, а iOS7 не крут с этим, поэтому он автоматически прокручивает минутное колесо до 5. My UIControlEventValueChanged обработчик получает вызов, а countDownDuration - 5 минут. (Все еще хорош.)
Теперь пользователь захватывает минутное колесо и перетаскивает его на 20. И... мой обработчик UIControlEventValueChanged не вызван. (Плохо.)
Если в этом случае у меня есть какое-то другое событие в пользовательском интерфейсе, выберите значение dateDuration. 20. Я не знал, что пользователь изменил его, на момент его изменения. Это очень повторяемо: это всегда происходит при первом изменении ПОСЛЕ того, как сборщик отказывается установить 0 (продвигаясь до 5 минут).
Обратите внимание, что это в iOS7; он не встречается в iOS6 (возможно, потому, что сборщик имеет идеальное содержание, которое должно быть установлено на 0 минут).
Итак... я что-то упустил? Или это настоящая ошибка в iOS7? И в последнем случае, кто-нибудь знает обход лучше, чем когда-либо таймер периодически проверять текущий интервал?
Ответы
Ответ 1
Я также могу подтвердить, что iOS 7.0.3 UIDatePicker имеет ошибку при использовании в режиме UIDatePickerModeCountDownTimer. Сборщик не срабатывает мишень-действие, связанное с этим событием UIControlEventValueChanged первый раз, когда пользователь изменяет значение с помощью прокрутки колеса. Он отлично работает для последующих изменений.
Ниже приведено эффективное решение. Просто приложите код, который устанавливает начальное значение countDownDuration в блоке отправки в основной цикл. Ваш метод целевого действия будет срабатывать каждый раз, когда колеса будут повернуты до нового значения. Этот подход почти не накладные расходы и работает достаточно хорошо на iPhone 4 и IPad 4.
dispatch_async(dispatch_get_main_queue(), ^{
self.myDatePicker.countDownDuration = (NSTimeInterval) aNewDuration ;
});
Ответ 2
Я все еще сталкивался с этой проблемой в 7.1, но добавляю следующее к обработчику UIControlEventValueChanged, который исправил его для меня.
// 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];
});
Ответ 3
Если у кого-то все еще есть проблемы с datepicker... Я использую Swift/iOS 8/Xcode 6.3
Поэтому решите проблему, которую вы не должны использовать
picker.countDownDuration = NSTimeInterval
вместо этого используйте setDate
picker.setDate(NSDate, animated: true)
он работает напрямую с viewDidLoad()
, не нужно использовать "очереди"
Ответ 4
Если у кого-то все еще есть проблемы с datepicker... Я использую Swift/iOS 8/Xcode 6.3
Чтобы решить проблему, вы не должны использовать picker.countDownDuration = NSTimeInterval
. Используйте .setDate(NSDate, animated: true)
.
он работает напрямую с viewDidLoad()
, не нужно использовать queues
Полный фрагмент:
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!
}
Ответ 5
Для Swift 3:
DispatchQueue.main.async(execute: {
yourPicker.countDownDuration = TimeInterval()
})
Ответ 6
Поскольку ответа еще не принято. Самое простое решение, которое работало для меня в быстром 3, - это просто сделать
datePicker.countDownDuration = секунды
in viewDidAppear вместо viewDidLoad
Ответ 7
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)