Question

I would like my textfield "DateText" to open a DatePicker (Year - Month - Day) with this type of value:

YYYY-MM-DD

Is there an easy way to change the keyboard?

Was it helpful?

Solution

You can "replace" the keyboard by using the inputView property of the UITextField:

- (void) initializeTextFieldInputView {
    UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectZero];
    datePicker.datePickerMode = UIDatePickerModeDate;
    [datePicker addTarget:self
                   action:@selector(dateUpdated:)
         forControlEvents:UIControlEventValueChanged];
    self.textField.inputView = datePicker;
}

- (void) dateUpdated:(UIDatePicker *)datePicker {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    self.textField.text = [formatter stringFromDate:datePicker.date];
}

UIDatePickers do not have a delegate like UIPickerViews so that is why an action must be added as if it were a UIButton. The : at the end of the selector declaration provides the UIDatePicker as a convenience to get the date when it has been changed. If you do not want to send an object in the method, you can get the UIDatePicker by referencing the UITextField's inputView:

UIDatePicker *datePicker = (UIDatePicker *)self.textField.inputView;

Lastly, when setting formats using NSDateFormatter, is good practice to create one method to return an NSDateFormatter object to make sure the format is consistent. At the very least, create a constant/macro once in your project that declares the format string.

EDIT

As asked by Pavan in the comments thread, if you want to add a done button above your keyboard, use the inputAccessoryView:

UIToolbar *toolbar = [[UIToolbar alloc] init];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(doneButtonWasPressed:)];
UIBarButtonItem *flexibleSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
toolbar.items = @[flexibleSeparator, doneButton];
self.textField.inputAccessoryView = toolbar;

EDIT 2, SWIFT

Seems like this Answer is quite outdated. Adding the implementation with Swift 3:

@IBOutlet weak var textField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    self.initializeTextFieldInputView()
}

func initializeTextFieldInputView() {
    // Add date picker
    let datePicker = UIDatePicker()
    datePicker.datePickerMode = .date
    datePicker.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged)
    self.textField.inputView = datePicker

    // Add toolbar with done button on the right
    let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 1))
    let flexibleSeparator = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonPressed(_:)))
    toolbar.items = [flexibleSeparator, doneButton]
    self.textField.inputAccessoryView = toolbar
}

func dateChanged(_ datePicker: UIDatePicker) {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    self.textField.text = formatter.string(from: datePicker.date)
}

You can also get the UIDatePicker by casting inputView in UITextField:

let datePicker = self.textField.inputView as? UIDatePicker

OTHER TIPS

Swift 2.0

I found Chris's answer above helpful, but needed it in Swift.

override func viewDidLoad() {
    super.viewDidLoad()

    // Present UIDatePicker for date input
    let datePicker = UIDatePicker(frame: CGRectZero)
    datePicker.datePickerMode = .Date
    datePicker.addTarget(self, action: #selector(SettingsViewController.DateChanged), forControlEvents: .ValueChanged)
    self.fromTimeField.inputView = datePicker
}

 func timeChanged(datePicker: UIDatePicker) {
    let formatter = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    self.fromTimeField.text = formatter.stringFromDate(datePicker.date)

Enable UIDatePicker using Editing Did Begin action while creating TextField action.

- (IBAction)textFieldAction:(id)sender
{
    // Place your code for UIDatePicker
    [textField resignFirstResponder]; //add this line in the end.
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top