28

我遇到了一个奇怪的效果,它看起来确实像是 iOS7 中的一个错误——但在过去,当我经常认为我在 Apple 的 API 中发现了一个错误时,结果证明这是我自己的误解。

我有一个带有 datePickerMode = UIDatePickerModeCountDownTimer 和 minuteInterval = 5 的 UIDatePicker。我将持续时间初始化为 1 小时,并将其呈现给用户,它显示为带有小时和分钟的两列选择器。(到目前为止,一切都很好。)

用户正在考虑“20 分钟”,因此将 Hour 列滚动到 0。此时选择器读取 0 小时和 0 分钟,而 iOS7 对此并不酷,因此它会自动将分钟轮滚动到 5。我的 UIControlEventValueChanged处理程序被调用,并且 countDownDuration 读取 5 分钟。(还好。)

现在用户抓住分钟轮并将其拖到 20。并且...我的 UIControlEventValueChanged 处理程序没有被调用。(坏的。)

如果我在 UI 中有其他事件,此时检查日期选择器,我确实看到 countDownDuration 设置为 20。但我无法知道用户更改了它,此时它已更改。这是非常可重复的:它总是发生在选择器拒绝设置为 0 之后的第一次更改(提前到 5 分钟)。

请注意,这是在 iOS7 中;它不会发生在 iOS6 中(可能是因为那里的选择器完全可以设置为 0 分钟)。

所以......我在这里错过了什么吗?或者这是iOS7中的真正错误?在后一种情况下,有没有人知道比让一些计时器定期检查当前间隔更好的解决方法?

4

7 回答 7

35

我还可以确认 iOS 7.0.3 UIDatePicker 在 UIDatePickerModeCountDownTimer 模式下使用时存在错误。当用户第一次通过滚动滚轮更改值时,选择器不会触发与 UIControlEventValueChanged 事件关联的目标操作。它适用于后续更改。

下面是一个有效的解决方法。只需将设置 countDownDuration 初始值的代码封装到主循环的调度块中即可。每次轮子旋转到新值时,您的目标操作方法都会触发。这种方法几乎没有开销,并且在 iPhone 4 和 iPad 4 上运行良好。

dispatch_async(dispatch_get_main_queue(), ^{
    self.myDatePicker.countDownDuration = (NSTimeInterval) aNewDuration ;
});

斯威夫特 5:

DispatchQueue.main.async {
    self.myDatePicker.countDownDuration = aNewDuration
}
于 2013-11-25T21:58:05.193 回答
6

我在 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];
});
于 2014-04-01T05:39:27.177 回答
2

如果有人仍然遇到日期选择器问题......我正在使用 Swift / iOS 8 / Xcode 6.3

所以解决你不应该使用的问题

picker.countDownDuration = NSTimeInterval

相反,使用 setDate

picker.setDate(NSDate, animated: true)

它直接工作viewDidLoad(),不需要使用`queues

于 2015-07-15T22:33:22.050 回答
2

由于尚未接受任何答案。在 swift 3 中对我有用的最简单的解决方案是简单地做

datePicker.countDownDuration = 秒

在 viewDidAppear 而不是 viewDidLoad

于 2017-06-25T23:22:55.480 回答
2

对于斯威夫特 3:

DispatchQueue.main.async(execute: {
    yourPicker.countDownDuration = TimeInterval() 
})
于 2017-04-03T14:41:50.153 回答
0

如果有人仍然遇到日期选择器问题......我正在使用 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!
}
于 2015-07-15T22:37:06.143 回答
-2

斯威夫特 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)
于 2017-12-11T07:24:38.617 回答