ios - 在 UITextView 下打开 UIDatePicker
问题描述
我正在编写一个应用程序,单击 UIExView 时会打开一个 UIDatePicker。我希望 UIDatePicker 在 UITextView 下方弹出,而不是从底部作为键盘出现。
我刚刚开始进行IOS应用程序开发,希望有人可以帮助我。
datePicker = UIDatePicker
和
inputTextfield = UITextField
我的代码:
//Function to create the datepicker
func createDatePicker(){
//create instance of the datepicker
datePicker = UIDatePicker()
//sets format, so only day month and year can be selected
//datePicker?.datePickerMode = .date
datePicker?.backgroundColor = .white
datePicker?.addTarget(self, action: #selector(ViewController.dateChanged(datePicker:)), for: .valueChanged)
//to limit the datepicker, you can not pick a date older than yesterday
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date())
datePicker?.minimumDate = yesterday
datePicker?.minuteInterval = 30
let loc = Locale(identifier: "de")
datePicker?.locale = loc
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.viewTapped(gesturRecognizer:)))
view.addGestureRecognizer(tapGesture)
inputTextfield.inputView = datePicker
//create a toolbar
let toolbar = UIToolbar()
toolbar.sizeToFit()
//add done button to the toolbar
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(doneClicked))
toolbar.setItems([doneButton], animated: true)
inputTextfield.inputAccessoryView = toolbar
}
//function to select a date
@objc func dateChanged(datePicker: UIDatePicker){
//selected date by the user
let dateFormate = DateFormatter()
//Jonas das ist vllt für dich relevant, man kann es so verändern wie man will
dateFormate.dateFormat = "MM/dd/yyyy"
inputTextfield.text = dateFormate.string(from: datePicker.date)
}
//function to close the datepicker, when tapping on the inputText again -handler method
@objc func viewTapped(gesturRecognizer: UITapGestureRecognizer){
view.endEditing(true)
}
//function to close the datepicker when clicking on the done button
@objc func doneClicked(){
self.view.endEditing(true)
}
解决方案
无需使用任何第三方库。这可以很容易地实现。我的理解是您希望选择器显示在文本字段下方,而不是作为输入视图而不是键盘显示。按照下面的代码来实现你想要的。
在这里,我的 ViewController 的名称是 TextFieldWithDatePickerVC。不要与名字混淆。使用以下代码,您无需使用任何第三方库即可轻松完成此操作。我还附上了一个输出视频和代码。
class TextFieldWithDatePickerVC: UIViewController {
lazy var inputTextfield: UITextField = {
let txtField = UITextField()
txtField.backgroundColor = .white
txtField.borderStyle = .roundedRect
txtField.translatesAutoresizingMaskIntoConstraints = false
txtField.placeholder = "Click me to open date picker"
return txtField
}()
lazy var datePicker: UIDatePicker = {
let picker = UIDatePicker()
picker.backgroundColor = .white
picker.addTarget(self, action: #selector(TextFieldWithDatePickerVC.dateChanged(_:)), for: .valueChanged)
let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date())
picker.minimumDate = yesterday
picker.minuteInterval = 30
let loc = Locale(identifier: "de")
picker.locale = loc
picker.translatesAutoresizingMaskIntoConstraints = false
return picker
}()
lazy var doneToolBar: UIToolbar = {
let toolbar = UIToolbar()
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(doneClicked))
toolbar.setItems([doneButton], animated: true)
toolbar.translatesAutoresizingMaskIntoConstraints = false
return toolbar
}()
lazy var pickerContainer: UIView = {
let view = UIView()
view.backgroundColor = .white
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
setupAutoLayout()
pickerContainer.isHidden = true
inputTextfield.delegate = self
hideDatePicker()
}
func showDatePickerView() {
DispatchQueue.main.async {
self.pickerContainer.isHidden = false
}
}
func hideDatePicker() {
DispatchQueue.main.async {
self.pickerContainer.isHidden = true
}
}
func setupAutoLayout() {
self.view.addSubview(inputTextfield)
self.view.addSubview(pickerContainer)
self.view.bringSubview(toFront: pickerContainer)
pickerContainer.addSubview(doneToolBar)
pickerContainer.addSubview(datePicker)
NSLayoutConstraint.activate([
inputTextfield.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 30),
inputTextfield.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -30),
inputTextfield.topAnchor.constraint(equalTo: view.topAnchor, constant: 60),
pickerContainer.topAnchor.constraint(equalTo: inputTextfield.bottomAnchor, constant: 5),
pickerContainer.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 30),
pickerContainer.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -30),
pickerContainer.heightAnchor.constraint(equalToConstant: datePicker.intrinsicContentSize.height + doneToolBar.intrinsicContentSize.height),
doneToolBar.topAnchor.constraint(equalTo: pickerContainer.topAnchor, constant: 0),
doneToolBar.leftAnchor.constraint(equalTo: pickerContainer.leftAnchor, constant: 0),
doneToolBar.rightAnchor.constraint(equalTo: pickerContainer.rightAnchor, constant: 0),
datePicker.bottomAnchor.constraint(equalTo: pickerContainer.bottomAnchor, constant: 0),
datePicker.leftAnchor.constraint(equalTo: pickerContainer.leftAnchor, constant: 0),
datePicker.rightAnchor.constraint(equalTo: pickerContainer.rightAnchor, constant: 0)
])
}
@objc func dateChanged(_ sender: UIDatePicker) {
print(sender.date)
inputTextfield.text = sender.date.description
}
@objc func doneClicked() {
hideDatePicker()
}
}
extension TextFieldWithDatePickerVC: UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.resignFirstResponder()
showDatePickerView()
}
}
推荐阅读
- sql-server - 将 yyyy-mm-dd 转换或转换为 dd-mon-yyyy am/pm
- couchdb - pouchdb 不会将所有文档同步到 couchdb
- python - 对象 MotorLatentCommandCursor 不能在“等待”表达式中使用
- ios - 如果我的设备中未安装 Instagram,则 Instagram 共享打开另一个应用程序
- r - 在 R 中使用 mutate 中的 lapply 进行不同长度的计算
- angular - 我的 sidenav 不推送内容,它克服了它
- python - Python 错误:无法将复数转换为浮点数
- scala - 函数式编程:从现有 Map 中获取具有更改值的新 Map
- java - 在 Java 中将图像数据保存在“PNG”文件中
- phpspreadsheet - 保存电子表格时如何避免Excel“格式错误”