Ошибка 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)