Search code examples
swiftuidatepicker

Date Picker Only Works After Clicking out of Text Field


I have a date picker I am using to set the value of a text field. It works great except that it only works the 2nd time that I tap into the text field, that is, the first time I tap the text field it shows me the standard keyboard. Then if I tap out of the textfield and back into it, it shows the datepicker. I've tried different variations of it, but it either doesn't work at all, or I get the same problem. This is how I set it up:

class ExpDateTableViewCell: UITableViewCell, UITextFieldDelegate {


@IBOutlet weak var textField: UITextField!


@IBAction func textFieldEditing(sender: UITextField) {

    let datePickerView:UIDatePicker! = UIDatePicker()

    datePickerView.datePickerMode = UIDatePickerMode.date

    sender.inputView = datePickerView

    datePickerView.addTarget(self, action: #selector(ExpDateTableViewCell.datePickerValueChanged), for: UIControlEvents.valueChanged)
}

func datePickerValueChanged(sender:UIDatePicker) {

    let dateFormatter = DateFormatter()

    dateFormatter.dateStyle = DateFormatter.Style.medium

    dateFormatter.timeStyle = DateFormatter.Style.none
    textField.text = dateFormatter.string(from: sender.date)


}


override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}

Solution

  • The problem is this code:

    @IBAction func textFieldEditing(sender: UITextField) {
        // ...
        sender.inputView = datePickerView
    }
    

    You are not setting the text field's inputView to the picker view until after the first time we have started editing. Thus we get the effect you correctly described: the second time we edit, the picker view is present.

    You need to set the text field's inputView much earlier, such as in awakeFromNib, before the user has a chance to edit the text field for the first time.