UIDatePicker valuechanged 不会更新第一次旋转,但每次旋转之后都会更新.. iOS

Posted

技术标签:

【中文标题】UIDatePicker valuechanged 不会更新第一次旋转,但每次旋转之后都会更新.. iOS【英文标题】:UIDate Picker valuechanged does not update the first spin, but does every spin after.. iOS 【发布时间】:2015-04-02 10:02:54 【问题描述】:

我在静态 TableViewCell 中嵌入了一个 UIDate Picker,目前我禁用了大部分代码,但负责日期选择器的代码除外。

我将日期选择器用作倒数计时器

除了一些常见的 outlet 和 vars 之外,这就是全部:

override func viewDidLoad() 
    super.viewDidLoad()

    //  tfName.delegate = self
    //  tfDescription.delegate = self
    //

    datePicker.countDownDuration = 60

    //  pickerValueChanged(self)




@IBAction func pickerValueChanged(sender: AnyObject) 

     seconds  = Int(datePicker.countDownDuration)
     hours  = seconds / 3600
    if hours == 0
        minutes = seconds / 60
     else
        minutes = seconds % 3600 / 60
    
    labelDuration.text = "\(hours) hours \(minutes) minutes"

我第一次更改 Picker 的值时,值更改函数根本不会触发,但它之后的旋转不会失败。

我尝试在viewDidLoad 中调用它,使用pickerValueChanged(self) 并且可以正常工作,但不能解决问题。我还注释掉了pickerValueChanged 函数和viewDidLoad 中的每一行代码,但它仍然没有触发第一次旋转..

感谢您的宝贵时间!

更新:添加图片

第一次旋转后,pickerValueChanged 不会被调用:

从第二次旋转开始,事件被调用并且标签被更新:

试过了:

执行: datePicker.setDate(NSDate(), animated: trueviewDidLoad() 解决了第一次旋转时没有调用事件的问题,但这会将日期选择器的初始状态设置为当前时间。由于我使用此控件来设置事件的持续时间,因此我想让它从 0 小时 1 分钟开始。 这可以通过datePicker.countDownDuration = 60 完成,但在此之后,主要问题又回来了。 因此,一个解决方案可能是将 DatePicker 设置为 1 分钟的 NSDate,但如何做到这一点?

解决方案:

var dateComp : NSDateComponents = NSDateComponents()
dateComp.hour = 0
dateComp.minute = 1
dateComp.timeZone = NSTimeZone.systemTimeZone()
var calendar : NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)!
var date : NSDate = calendar.dateFromComponents(dateComp)!

datePicker.setDate(date, animated: true)

【问题讨论】:

【参考方案1】:

我想出了以下解决方案,用 0 小时 1 分钟初始化 datePicker 组件(在倒数计时器模式下),它在第一次旋转时直接响应。由于这似乎是一个错误,如果您希望文本标签在 datePicker 更改时更新其值并且它一开始就没有更新它的值,这将是非常令人沮丧的:

var dateComp : NSDateComponents = NSDateComponents()
dateComp.hour = 0
dateComp.minute = 1
dateComp.timeZone = NSTimeZone.systemTimeZone()
var calendar : NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)!
var date : NSDate = calendar.dateFromComponents(dateComp)!

datePicker.setDate(date, animated: true)

timeZone 组件对于我的实现来说并不是真正需要的。

【讨论】:

这一直有效,直到 DatePicker 不消失(例如,如果我有显示或隐藏它的表格单元格)。如果我打开 DatePicker 所在的单元格,问题又出现了,即使设置 DatePicker 的日期也无济于事。这太疯狂了....【参考方案2】:

似乎和动画参数有关。 你只需要这一行:

datePicker.setDate(date, animated: true)

【讨论】:

这对我来说似乎是个问题。我曾经使用animated: false 设置日期,将其更改为true 使我的目标操作在第一次更改值时也被调用。【参考方案3】:

不久前,我发现了另一个与此类似的问题。它是关于从tableView:didSelectRowAtIndexPath: 中呈现一个视图控制器,问题是新控制器需要很长时间才能真正显示出来。解决方法之一是在主队列上使用dispatch_async。在这种情况下,同样适用于我。

在我的viewDidLoad 中,我在主队列上异步调度了选择器设置代码,在我的例子中,它甚至在第一次选择时就开始响应valueChanged 事件:

DispatchQueue.main.async 
    self.pickerView.datePickerMode = .countDownTimer
    self.pickerView.minuteInterval = 5
    self.pickerView.countDownDuration = 15

【讨论】:

适用于 Swift 4.2【参考方案4】:

这是@Henk-Martijn 的解决方案针对 Swift 3 进行了更新和简化

let calendar = Calendar(identifier: .gregorian)
let date = DateComponents(calendar: calendar, hour: 1, minute: 30).date!
datePicker.setDate(date, animated: true)

使用上面的代码而不是类似的代码:

datePicker.countDownDuration = 5_400

【讨论】:

【参考方案5】:

和上面类似的问题,我用过

DispatchQueue.main.asyncAfter(deadline: .now()) 
   self.datePicker.countDownDuration = 60

把它放到下一个runloop。似乎是一个可行的解决方法。

【讨论】:

【参考方案6】:

我认为你应该尝试实现这个委托

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component

【讨论】:

我之前尝试为 Date Picker 设置一个委托,但是这个控件没有像 PickerView 那样有一个委托,正如 Andrea 也解释的那样 哦,我明白了。你看到这个帖子了吗:***.com/questions/19251803/… 他们所说的bug似乎还在。在 viewDidLoad 中设置 datePicker.setDate(NSDate(), animated: true) 部分解决了这个问题。 DatePicker 现在将第一次旋转的值更新为,但它会将小时和分钟与本地时间同步。而且我希望它从 1 分钟开始,我使用 datePicker.countDownDuration = 60 执行此操作,但这再次破坏了该功能:D。所以我需要用(0h)的NSDate常数初始化选择器,1分钟。但我不知道如何归档这个【参考方案7】:

实际上,您只需要viewDidLoad 中设置datePicker.countDownDuration,而是将其添加到viewDidAppear 或更高版本。

【讨论】:

我也在 viewWillAppear 工作过。【参考方案8】:

我不知道我是否遇到了您的问题,但日期选择器使用目标操作模式工作,并且在您更改值时会触发此机制。 因此,如果问题是显示的第一个值,则应初始化变量,将其作为“默认”值。

【讨论】:

发生的情况是,我第一次给 Date Picker 一个 *swing" 它会旋转到某个值,但根本不会触发 Value Changed 事件。但是第二次和之后的摆动确实会触发事件。即使从 viewDidLoad 触发事件也不会改变问题的行为。

以上是关于UIDatePicker valuechanged 不会更新第一次旋转,但每次旋转之后都会更新.. iOS的主要内容,如果未能解决你的问题,请参考以下文章

UIDatePicker 默认返回 Null?

UIDatePicker

iOS14 UIDatePicker 有一个偏移量

UIDatePicker 泄漏

UIdatePicker&UIPickerView简单使用

使用UIAppearance自定义iOS UIDatepicker