【问题标题】:UIDate Picker valuechanged does not update the first spin, but does every spin after.. iOSUIDatePicker valuechanged 不会更新第一次旋转,但每次旋转之后都会更新.. 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)

【问题讨论】:

    标签: ios datepicker


    【解决方案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 也解释的那样
        • 哦,我明白了。你看到这个帖子了吗:stackoverflow.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 触发事件也不会改变问题的行为。
        猜你喜欢
        • 1970-01-01
        • 2020-07-03
        • 2012-07-05
        • 1970-01-01
        • 2017-06-21
        • 1970-01-01
        • 1970-01-01
        • 2012-02-17
        • 1970-01-01
        相关资源
        最近更新 更多