具有 UIControlEvents.valueChanged 的日期选取器不适用于第一个值更改事件



我正在使用下面的代码来了解有关日期选择器的信息。它有效,但是很奇怪的是,当我第一次滚动日期选择器时,预期的更改不会发生。之后,它将正常工作。想知道发生了什么。

import UIKit
import Foundation
class ViewController: UIViewController {
// Place this code inside your ViewController or where you want ;)
var txtField: UITextField = UITextField(frame: CGRect(x: 100, y: 0, width: 300, height: 50))
override func viewDidLoad() {
    super.viewDidLoad()
    // date picker setup
    let datePickerView:UIDatePicker = UIDatePicker()
    // choose the mode you want
    // other options are: DateAndTime, Time, CountDownTimer
    datePickerView.datePickerMode = UIDatePickerMode.countDownTimer
    // choose your locale or leave the default (system)
    //datePickerView.locale = NSLocale.init(localeIdentifier: "it_IT")
    datePickerView.addTarget(self, action: #selector(onDatePickerValueChanged(_:)), for: UIControlEvents.valueChanged)
    txtField.inputView = datePickerView
    // datepicker toolbar setup
    let toolBar = UIToolbar()
    toolBar.barStyle = UIBarStyle.default
    toolBar.isTranslucent = true
    let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
    let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(ViewController.doneDatePickerPressed))
    // if you remove the space element, the "done" button will be left aligned
    // you can add more items if you want
    toolBar.setItems([space, doneButton], animated: false)
    toolBar.isUserInteractionEnabled = true
    toolBar.sizeToFit()
    txtField.inputAccessoryView = toolBar
    self.view.addSubview(txtField)
}
func doneDatePickerPressed(){
    self.view.endEditing(true)
}
func onDatePickerValueChanged(_ sender: UIDatePicker) {
    let (h, m, _) = secondsToHoursMinutesSeconds (duration: sender.countDownDuration)
    self.txtField.text = String("(h) Hours  (m) Minutes")
}
func secondsToHoursMinutesSeconds (duration : Double) -> (Int, Int, Int) {
    let seconds:Int = Int(duration)
    return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
}

奇怪。这似乎是设置为UIDatePickerMode.countDownTimer模式的日期选择器中的错误。

您可以通过实现UITextFieldDelegate方法textFieldShouldBeginEditing(_:)并在短延迟后设置Picker的值来解决失败情况的最多。这是我的测试项目中的代码。(在我的项目中,时间间隔字段称为optionalTimeField,时间间隔值是一个可选的称为optionalTime。您需要更改它以适合您的代码:

编辑:

请参阅新功能textfield(_:,syredchangecharactersinrange :, replacementstring :)下面

extension ViewController: UITextFieldDelegate {
  
   //Add this function to prevent keyboard editing
   func textField(_ textField: UITextField, 
           shouldChangeCharactersIn range: NSRange, 
           replacementString string: String) -> Bool {
       return false
  }
  func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    if textField === optionalTimeField {
      //Set the time interval of the date picker after a short delay
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        self.datePickerView.countDownDuration = self.optionalTime ?? 60
      }
      
    }
    return true
  }
}

我建议向Apple Bug Reporter提交错误报告。基于线程@Santosh链接,从iOS 7开始,该错误似乎已经存在于UIDatePicker中,这很糟糕。

我看不到工作的一个错误是,如果您尝试选择一个时间间隔为0小时,0分钟,则切换到1分钟,此后,您选择的下一个时间间隔是没有触发值更改的方法。

间隔日期选择器有各种奇怪的事情,例如您无法指定它选择秒的事实。如果足够重要,您可能需要根据通用UIPickerView创建自己的时间间隔选择器。不应该那么难。(尤其是如果您不必担心使用不同时间格式的多个地区的本地化。)您只需创建一个带有小时,分钟和(选择)秒的旋转器的选择器视图,请使用您的法律价值观填充它,你走了。您可以将其设置为具有可选的最小和最大间隔值。

相关内容

最新更新