首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用UIControlEvents.valueChanged的日期选择器不适用于第一个值更改事件

使用UIControlEvents.valueChanged的日期选择器不适用于第一个值更改事件
EN

Stack Overflow用户
提问于 2016-12-02 14:37:35
回答 1查看 2.6K关注 0票数 4

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

代码语言:javascript
复制
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)
}

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-02 16:56:50

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

您可以通过实现UITextFieldDelegate方法textFieldShouldBeginEditing(_:)并在短时间延迟后设置选择器的值来避免大多数失败情况。这是我的测试项目的代码。(在我的项目中,时间间隔字段称为optionalTimeField,而时间间隔值是可选的,称为optionalTime。您需要修改它以适应您的代码:

编辑:

参见新函数textField(_:,shouldChangeCharactersInRange:,replacementString:)

代码语言:javascript
复制
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
  }
}

我建议向苹果的bug报告提交一份报告。基于链接的线程@Santosh,看起来这个bug从UIDatePicker 7开始就已经存在了,这是很糟糕的。

有一个bug我没有看到-解决之道是,如果您尝试选择一个0小时,0分钟的时间间隔,它会切换到1分钟,然后,您选择的下一次时间间隔不会触发值更改方法。

关于间隔日期选择器有很多奇怪的地方,比如您不能指定它来选择秒。如果这足够重要,您可能希望基于通用UIPickerView创建自己的时间间隔选择器。应该没那么难。(特别是如果您不需要担心使用不同时间格式的多个地区的本地化。)您只需在几个小时、分钟和(可选的)秒内创建一个带有旋转器的选择器视图,然后用您的合法值填充它,然后就可以离开了。您可以将其设置为具有可选的最小和最大间隔值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40934689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档