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

UIDate Picker valuechanged does not update the first spin, but does every spin after.. iOS

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

我正在使用日期选择器作为倒数计时器

所以这就是全部,除了一些常用的 outlets 和 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 的 NSDate 设置为 1 分钟,但是该怎么做呢?

解法:

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)

我不知道我是否遇到了你的问题,但日期选择器使用目标操作模式工作,当你更改值时它会触发此机制。
因此,如果问题是显示的第一个值,您应该将变量初始化为 "default" 值。

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

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

我想出了以下解决方案来将 datePicker 组件(在倒数计时器模式下)初始化为 0 小时 1 分钟,它在第一次旋转时直接响应。因为这似乎是一个错误,如果您希望文本标签在 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.setDate(date, animated: true)

前段时间我发现了另一个与这个有点相似的问题。它是关于从 tableView:didSelectRowAtIndexPath: 中呈现一个视图控制器,问题是新控制器实际出现需要很多时间。解决方法之一是在主队列上使用 dispatch_async。在这种情况下,同样适用于我。

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

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

这是@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

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

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

将它放在下一个运行循环中。似乎是一个可行的解决方法。

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

当您将 DatePicker 用作文本字段的输入视图时,

None 这些解决方案有效。

我在下面附上了我的代码。我仍在为此寻找一个好的解决方案,因为上面的 none 解决了我的场景中的问题。

self.durationDatePicker.datePickerMode = .countDownTimer
self.durationDatePicker.preferredDatePickerStyle = .wheels
self.durationDatePicker.minuteInterval = 5
self.durationDatePicker.addTarget(self, action: #selector(CreateEventDetailsViewController.datePickerValueChanged(picker:)), for: .valueChanged)
self.durationTextField.inputView = self.durationDatePicker