How to bring up a date picker when a date field is tapped?

28,070

Solution 1

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.

Solution 2

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

Solution 3

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.

Share:
28,070
Greg
Author by

Greg

Updated on July 09, 2022

Comments

  • Greg
    Greg almost 2 years

    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)
    }
    
  • Greg
    Greg about 9 years
    I modified the code as you wrote but I get the same behavior. When I tap on the field the keyboard comes up.
  • Greg
    Greg about 9 years
    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?
  • Ganesh Somani
    Ganesh Somani about 9 years
    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
  • Greg
    Greg about 9 years
    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.
  • halfred
    halfred over 7 years
    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().
  • ucelme
    ucelme over 4 years
    When I use this code and then click again on textfield, date move forward to 3 dimensions. How this can be fixed?