问题
I try to get string from textfield, then convert it to date and put this value in datepicker. But for some reason it fails everytime and I get: "There is issue in dateformatter. Not able to convert string to Date".
I don't understand what I'm doing wrong and how I get this works.
My code:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var DOBTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
DOBTextField.addInputViewDatePicker(target: self, selector: #selector(doneButtonPressed), textFieldText: DOBTextField.text)
}
@objc func doneButtonPressed() {
if let datePicker = self.DOBTextField.inputView as? UIDatePicker {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .none
self.DOBTextField.text = dateFormatter.string(from: datePicker.date)
}
self.DOBTextField.resignFirstResponder()
}
}
extension UITextField {
func addInputViewDatePicker(target: Any, selector: Selector , textFieldText: String?) {
let screenWidth = UIScreen.main.bounds.width
let datePicker = UIDatePicker(frame: CGRect(x: 0, y: 0, width: screenWidth, height: 216))
datePicker.datePickerMode = .date
self.inputView = datePicker
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .none
if textFieldText != nil {
if let date = dateFormatter.date(from: textFieldText!) {
datePicker.date = date
} else {
print("There is issue in dateformatter. Not able to convert string to Date ")
}
}
else {
datePicker.date = Date()
}
//Add Tool Bar as input AccessoryView
let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: screenWidth, height: 44))
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelBarButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelPressed))
let doneBarButton = UIBarButtonItem(title: "Done", style: .plain, target: target, action: selector)
toolBar.setItems([cancelBarButton, flexibleSpace, doneBarButton], animated: false)
self.inputAccessoryView = toolBar
}
@objc func cancelPressed() {
self.resignFirstResponder()
}
}
I don't understand what I'm doing wrong and why this code doesn't work. May be someone can help me resolve this issue?
回答1:
As I see when you call addInputViewDatePicker
on viewDidLoad
, the value of textFieldText
is ""
that's why you see your print from start
you can try use this code (but, I guess, you can optimize it):
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var DOBTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
prepareDOBTextField()
DOBTextField.addInputViewDatePicker(target: self, selector: #selector(doneButtonPressed), textFieldText: DOBTextField.text)
}
@objc func doneButtonPressed() {
if let datePicker = self.DOBTextField.inputView as? UIDatePicker {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .none
self.DOBTextField.text = dateFormatter.string(from: datePicker.date)
}
self.DOBTextField.resignFirstResponder()
}
func prepareDOBTextField() {
let date = Date()
let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .none
let result = formatter.string(from: date)
self.DOBTextField.text = result
}
}
extension UITextField {
func addInputViewDatePicker(target: Any, selector: Selector , textFieldText: String?) {
let screenWidth = UIScreen.main.bounds.width
let datePicker = UIDatePicker(frame: CGRect(x: 0, y: 0, width: screenWidth, height: 216))
datePicker.datePickerMode = .date
self.inputView = datePicker
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .none
if textFieldText != nil && textFieldText != "" {
if let date = dateFormatter.date(from: textFieldText!) {
datePicker.date = date
} else {
print("There is issue in dateformatter. Not able to convert string to Date ")
}
}
else {
datePicker.date = Date()
}
//Add Tool Bar as input AccessoryView
let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: screenWidth, height: 44))
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelBarButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelPressed))
let doneBarButton = UIBarButtonItem(title: "Done", style: .plain, target: target, action: selector)
toolBar.setItems([cancelBarButton, flexibleSpace, doneBarButton], animated: false)
self.inputAccessoryView = toolBar
}
@objc func cancelPressed() {
self.resignFirstResponder()
}
}
回答2:
You can do this by follow my code below.
@objc func doneButtonPressed() {
//Converting string to date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let date = dateFormatter.date(from: DOBTextField.text!)
//Sets the date in the date picker
datepicker.setDate(date!, animated: true)
}
So first you're converting your textfield (DOBTextField.text) into Date.
Right after you're setting the datePicker to be the correct date.
In this case you will have to enter exactly like this in the textfield: "2019-12-18 14:50"
回答3:
Solved this question. I get rid of extenstion and write code for datepicker in ViewController.
import UIKit
class ViewController: UIViewController {
@IBOutlet var textField: UITextField!
let datePicker = UIDatePicker()
override func viewDidLoad() {
super.viewDidLoad()
createDatePicker()
}
func createDatePicker() {
textField.inputView = datePicker
datePicker.datePickerMode = .date
datePicker.maximumDate = Date()
let toolbar = UIToolbar()
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(doneClicked))
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
toolbar.setItems([flexibleSpace, doneButton], animated: true)
textField.inputAccessoryView = toolbar
}
@objc func doneClicked() {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .none
textField.text = dateFormatter.string(from: datePicker.date)
self.view.endEditing(true)
}
}
After I added to viewWillAppear actual values of datepicker:
override func viewWillAppear(_ animated: Bool) {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .none
datePicker.date = dateFormatter.date(from: textfield.text!)!
}
来源:https://stackoverflow.com/questions/59392923/cannot-convert-string-to-date-for-datepicker