3

I have a view with a text field for date. I want the current date to default to "today" but if the user wants to put in a different date, he can tap the field to bring up a date picker (already added to the view). I found a similar question and answer that I though was going to work. I have no errors but when I tap on the date field the keyboard comes up, not the date picker.

@IBOutlet var enterDate: UITextField!

@IBAction func dateTapped(sender: UITextField) {

    //code for what to do when date field is tapped
    var datePickerView  : UIDatePicker = UIDatePicker()
    datePickerView.datePickerMode = UIDatePickerMode.Date
    sender.inputView = datePickerView
    datePickerView.addTarget(self, action: Selector("handleDatePicker:"), forControlEvents: UIControlEvents.ValueChanged)
}

func handleDatePicker(sender: UIDatePicker) {
    var dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "dd MMM yyyy"
    enterDate.text = dateFormatter.stringFromDate(sender.date)
}
belwood
  • 3,320
  • 11
  • 38
  • 45
Greg
  • 427
  • 3
  • 7
  • 21
  • What kind of object do you click. Is it a `UITextField`?? How have you added this textfield? – Ganesh Somani Apr 17 '15 at 01:27
  • Yes, it is a UITextField called enterDate. I'm not sure what you are asking by "How have you added this textField?" I added a text field to the view and then created the outlet called enterDate. Does that answer your question? – Greg Apr 17 '15 at 02:42
  • Here's what worked for me in Swift 4 - https://stackoverflow.com/a/56115141/2006730 – Maybelle Pacate May 13 '19 at 15:09

3 Answers3

8

Create Extension of UITextField and add the following methods.

 extension UITextField {

   func addInputViewDatePicker(target: Any, selector: Selector) {

    let screenWidth = UIScreen.main.bounds.width

    //Add DatePicker as inputView
    let datePicker = UIDatePicker(frame: CGRect(x: 0, y: 0, width: screenWidth, height: 216))
    datePicker.datePickerMode = .date
    self.inputView = datePicker

    //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()
   }
}

In ViewController Add a UITextField and create IBOutlet:-

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var DOBTextField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()

    DOBTextField.addInputViewDatePicker(target: self, selector: #selector(doneButtonPressed))

}

@objc func doneButtonPressed() {
    if let  datePicker = self.DOBTextField.inputView as? UIDatePicker {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .medium
        self.DOBTextField.text = dateFormatter.string(from: datePicker.date)
    }
    self.DOBTextField.resignFirstResponder()
 }
}
Yogendra Singh
  • 2,063
  • 25
  • 20
  • When I use this code and then click again on textfield, date move forward to 3 dimensions. How this can be fixed? – ucelme Dec 17 '19 at 09:57
4

I guess you are taking a UITextField for the input but you have not established a connection between the datePicker and textfield.

Have a look at this answer here

In swift this can be done by textfield.inputView = datePickerView. After this the click on textfield will be handled by datePicker, but you should initialize datePicker before doing this.

Community
  • 1
  • 1
Ganesh Somani
  • 2,280
  • 2
  • 28
  • 37
  • I have looked at the answer you linked to. Is that swift code? There is much there that I have never seen before. Also, I do not understand your comment "hooked up the datePicker with the textField". What does that mean? – Greg Apr 17 '15 at 02:45
  • by hooking up the textfield i mean setting a connection between the TextField and Date Picker. In swift that can be something like `txtField.inputView = datePickerView`. After that, the click event should be handled by the datePicker. However, you should initialize the datePicker before hand like in `viewDidLoad`, etc – Ganesh Somani Apr 17 '15 at 03:12
  • Thank you for the clarification. I have hooked up the text field and date picker with the code enterDate.inputView = datePickerView. Still when I run the code I get the keyboard and not the date picker. When you say initialize the datePicker, do you mean run that code in the viewDidLoad method? Do I remove that line from what I have written and put it in the viewDidLoad method or do I move all of the code there? I'm afraid I need a little hand holding here. – Greg Apr 17 '15 at 04:41
  • When the view loads the default inputView will be assigned to your txtField so you need to assign the new datePicker to your txtField.inputView on viewDidLoad(). – halfred Dec 14 '16 at 16:36
1

I don't think you need the dateTapped action. If you put all your setup code in a place where you initialize the text field I think it will work automatically.

I think the problem you're seeing is due to you setting the inputView only after the text field is pressed. If you set it before (e.g. enterDate.inputView = datePickerView) the system should handle the rest. In other words, when that text field becomes the first responder it will show the inputView instead of the regular keyboard.

nebs
  • 4,939
  • 9
  • 41
  • 70
  • I modified the code as you wrote but I get the same behavior. When I tap on the field the keyboard comes up. – Greg Apr 17 '15 at 02:43