UIDatePicker错误?点击最小内部后的UIControlEventValueChanged

时间:2013-11-24 22:33:52

标签: ios uidatepicker uicontrolevents

我遇到了一个奇怪的效果,肯定看起来像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中的真正错误?在后一种情况下,是否有人知道解决方案比定时器定期检查当前间隔更好?

7 个答案:

答案 0 :(得分:33)

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

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

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

答案 1 :(得分: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];
});

答案 2 :(得分:2)

如果有人仍然遇到datepicker问题... 我正在使用Swift / iOS 8 / Xcode 6.3

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

picker.countDownDuration = NSTimeInterval

而是使用setDate

picker.setDate(NSDate, animated: true)

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

答案 3 :(得分:1)

如果有人仍然遇到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!
}

答案 4 :(得分:1)

对于Swift 3:

SELECT FORMAT(1, '00000') AS PaddedNumber

答案 5 :(得分:1)

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

  

datePicker.countDownDuration =秒

在viewDidAppear而不是viewDidLoad

答案 6 :(得分:0)

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)