首次使用UIDatePickers。首先,我只是尝试使用从datePicker中选择的任何值更新文本字段(在倒计时模式下设置)。
它可以工作,但只是用户第二次选择时间。我的动作,durationSelected()仅被第二次调用,因此更新textField没有问题。
以下是我在故事板中配置日期选择器的方法:
以下是价值变更触发的操作:
来自DetailViewController.m的
- (IBAction)durationSelected:(UIDatePicker *)sender
{
self.durationTextField.text = [NSString stringWithFormat:@"%f seconds", sender.countDownDuration];
}
我尝试过设置默认值,但没有效果。
有关正在发生的事情的任何想法?
谢谢!
答案 0 :(得分:22)
在UIDatePickerModeCountDownTimer模式下使用iOS 7.0.3 UIDatePicker时,我看到了类似的错误。选择器不会触发与UIControlEventValueChanged事件关联的目标操作第一时间,用户通过滚动滚轮来更改值。它适用于后续更改。
以下是一种有效的解决方法。只需将调度块中countDownDuration的初始值设置为主循环的代码。每次将车轮旋转到新值时,您的目标操作方法都会触发。这种方法几乎没有开销,在iPhone 4和iPad 4上运行良好。
dispatch_async(dispatch_get_main_queue(), ^{
self.myDatePicker.countDownDuration = (NSTimeInterval) aNewDuration ;
});
答案 1 :(得分:16)
这似乎是UIDatePicker的iOS 7实现中的一个错误。我建议在上面备一个雷达。
在iOS 6 SDK上构建并在iOS 6设备上运行将起作用,而在iOS 7设备上运行则不行。
您可以通过将此行代码添加到- (void)viewDidLoad
方法
[self.datePicker setDate:[NSDate date] animated:YES];
答案 2 :(得分:4)
我不确定,这是一个有根据的猜测:
可能是iOS只跟踪日期选择器的值变化,因为它们是由动画轮子引起的。因此它设置了第一个“滚动”的值,但只检测到第二个“滚动”的值。
正如我所说,我无法确定原因,但修复应该很简单:只需在使用setDate: animated:
加载视图后以编程方式设置启动日期:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.picker setDate:[NSDate dateWithTimeIntervalSinceNow:0] animated:true ];
}
这似乎对我有用。
答案 3 :(得分:0)
您可以尝试设置countDownTimer值(如果您在countdowntimer模式下使用datePicker)。但请确保在显示选择器后将此属性设置在完成块内。
答案 4 :(得分:0)
在呈现选择器之后,以下代码在Xcode 9.4 beta,iOS 11.4中为我工作。
picker.countDownDuration = 0
picker.countDownDuration = 3600 // 1 Hour
答案 5 :(得分:0)
我在使用Swift 4.0的Xcode 10,iOS 12.0.1中成功实现了以下目标:
使用其他答案作为指导,我最终使UITextField
s代表响应:
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if let _ = textField.inputView as? UIDatePicker {
//In my case I had more than one text field who's delegate would fire this method
//So I checked to see if the input view was a date picker before continuing
//If you have only one "delegated" text field then there's probably
//no need for a check
perform(#selector(setDatePicker), with: nil, afterDelay: 0)
}
return true
}
@objc func setDatePicker() {
Thread.doBlockOnMainThread {
self.theTimePicker.countDownDuration = 1000 //or whatever
}
}
其中Thread.doBlockOnMainThread(_)
是:
extension Thread {
class func doBlockOnMainThread(_ block: () -> Void) {
if !Thread.isMainThread {
DispatchQueue.main.sync(execute: {
block()
})
} else {
block()
}
}
}
顺便说一句,我发现这不仅是UIDatePicker
第一次出现时,而且是用户错误地尝试将倒计时值设置为零时。 DatePicker会自动按预期移动到1
,但随后的下一个值更改也不会触发所需的目标。
答案 6 :(得分:0)
还有一个类似的错误,即您将其旋转为全0之后,它不会在第一次更改时触发,并且会滑动到第一分钟。
鉴于以上两者,我只是使用蛮力方法解决了所有这些废话(假设苹果根本不愿意对此进行修复)。
在viewDidLoad()中:
NSTimer scheduledTimerWithTimeInterval:0.750 repeats:YES block:^(NSTimer * _Nonnull timer) {
[self timePickerDidChange:nil];
}];
只需继续自己调用更改事件即可。只要它不超过当前值(即self.timePicker.countDownDuration
,它就可以正常工作。请确保您的didChange代码不会像网络调用那样做大事:)
答案 7 :(得分:0)
以上所有内容均不适用于iOS 13 / XCode 11.4.1。我的解决方案是对文本字段UITextFieldDelegate使用“ textFieldDidBeginEditing”委托方法,因为需要查看日期选择器并对其进行动画处理以模拟“第一个”选择,因此在第二个选择(对用户而言是第一个选择)上,UIControlEventValueChanged方法是触发。所以,像这样:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[self.datePicker setDate: date]; //date is whatever date you want to set
}
在我的方法上,第一次运行时,我使用NSCalendar和NSDateComponents将date变量设置为5分钟间隔,这正是我所需要的,然后设置date = self.datePicker.date。
除用户手动选择0分钟的情况外,此方法有效。