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: true
在 viewDidLoad()
解决了事件在第一次旋转时没有被调用的问题,但这会将日期选择器的初始状态设置为当前时间。因为我使用这个控件来设置一个事件的持续时间,所以我想让它从 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
我在静态 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: true
在 viewDidLoad()
解决了事件在第一次旋转时没有被调用的问题,但这会将日期选择器的初始状态设置为当前时间。因为我使用这个控件来设置一个事件的持续时间,所以我想让它从 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
,或稍后。
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