UIDatePicker 错误? UIControlEventValueChanged 达到最小内部后

Posted

技术标签:

【中文标题】UIDatePicker 错误? UIControlEventValueChanged 达到最小内部后【英文标题】:UIDatePicker bug? UIControlEventValueChanged after hitting minimum internal 【发布时间】:2013-12-09 12:35:06 【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

转载。对我来说似乎是一个错误。 我在 iOS 12.1 中仍然看到这个问题。从用户的 cmets 来看,这个 bug 至少也出现在 iOS 7.1、8、8.1 和 10 中。 问题在 iOS 13 中仍然存在... 【参考方案1】:

我还可以确认 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

【讨论】:

@Rich 我仍然可以在运行 iOS 7.1 的 iPhone 上重现 iOS SDK 7.1 上的问题。你有什么配置解决了这个问题? 这很奇怪!这个错误在 iOS 7.1 上仍然存在,但这个答案中的修复对我有用。谢谢。 我在使用 Xcode6.1.1 和 iOS 8.1 时遇到了同样的问题 有人知道是否为此打开了雷达吗? iOS 9 中仍然存在一个单独的错误,当您尝试选择 00:00 的时间(低于我的最小间隔 10 分钟)时会发生该错误。所以日期选择器会自动切换到 00:10,之后,当你尝试切换到 02:00 时,不会调用 value changed 事件。每次日期选择器低于间隔时都会发生这种情况。这是解决方法。 - (IBAction)datePickerValueChanged:(UIDatePicker *)sender if (sender.countDownDuration == (sender.minuteInterval * 60)) sender.countDownDuration = sender.countDownDuration; 【参考方案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];
);

【讨论】:

这在 iOS 8 下对我有用,而 Positron 的解决方案却没有。 这里也一样,好像需要延迟 这对我有用,或者以同样的方法,如果你不想延迟,只需在主队列中运行它dispatch_async(dispatch_get_main_queue(), ^ [keyboard setCountDownDuration: keyboard.countDownDuration]; );【参考方案3】:

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

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

picker.countDownDuration = NSTimeInterval

改为使用 setDate

picker.setDate(NSDate, animated: true)

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

【讨论】:

【参考方案4】:

对于 Swift 3:

DispatchQueue.main.async(execute: 
    yourPicker.countDownDuration = TimeInterval() 
)

【讨论】:

【参考方案5】:

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

datePicker.countDownDuration = 秒

在 viewDidAppear 中而不是 viewDidLoad

【讨论】:

【参考方案6】:

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

要解决问题,您不应使用picker.countDownDuration = NSTimeInterval。使用.setDate(NSDate, animated: true)

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

完整的sn-p:

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!

【讨论】:

感谢您提供用于时间间隔到日期转换的快速代码。这对我有用。疯了,这个问题在 iOS 10 中仍然存在。 这并没有解决我在 iOS 14 上的问题【参考方案7】:

斯威夫特 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)

【讨论】:

以上是关于UIDatePicker 错误? UIControlEventValueChanged 达到最小内部后的主要内容,如果未能解决你的问题,请参考以下文章

在“UIDatePicker”类型的对象上找不到属性“preferredDatePickerStyle”

如何使用 KIF 框架自动化 UIDatePicker 以选择过去的日期

保存来自 UIDatePicker 的选择

UIDatePicker 15 分钟增量 Swift

UIDatePicker 默认返回 Null?

UIDatePicker