0

I have 2 problems with my UIDatePicker:

  • I have to tap 2 times on my UITextField to appear the UIDatePicker

  • When I select something on a row, the day for exemple, the UIDatePicker is closing just after, I think it could be better to block it and have a button "done"

code:

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

@IBAction func tfDateNaissanceEditing(sender: UITextField) {
    let datePickerView:UIDatePicker = UIDatePicker()

    datePickerView.datePickerMode = UIDatePickerMode.Date

    sender.inputView = datePickerView

    datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
    tfDateNaissance.resignFirstResponder()

}

func datePickerValueChanged(sender: UIDatePicker) {
    let dateFormatter = NSDateFormatter()

    dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle

    dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle

    tfDateNaissance.text = dateFormatter.stringFromDate(sender.date)
    tfDateNaissance.resignFirstResponder()
}
Nikunj
  • 655
  • 3
  • 13
  • 25
Ben
  • 761
  • 1
  • 12
  • 35
  • The `resignFirstResponder()` is the method that closes the keyboard (in this case, the date picker). You will have to add the "done" button manually, for example see this link: http://stackoverflow.com/questions/20192303/how-to-add-a-done-button-to-numpad-keyboard-in-ios – aramusss Dec 23 '15 at 09:10
  • @aramusss thanks, your link is on Objective-C langage – Ben Dec 23 '15 at 09:16
  • 2
    @Ben, that's true. Although you choose to use Swift, but it's important for an iOS developer to understand Obj-C code. – zc246 Dec 23 '15 at 09:26
  • @Ben if you leave `tfDateNaissance.resignFirstResponder()` in your `datePickerValueChanged method`, the picker will close as soon as the value change. I personally add a toolbar to the picker with a done button to handle the `resignFirstResponder`. Check the answer. Hope it helps. – Mat Dec 23 '15 at 09:52

3 Answers3

1

If you leave tfDateNaissance.resignFirstResponder() in your datePickerValueChanged method, the picker will close as soon as the value change. You have to add a cancel/done button and put resignFirstResponder() inside that function. I tested the code and it works.

What I personally do is the following, first I declare the datePicker

let datePickerView  : UIDatePicker = UIDatePicker()

then in viewDidLoad

override func viewDidLoad() {

  datePickerView.datePickerMode =  UIDatePickerMode.Date
  datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)

  self.tfDateNaissance.inputView = self.datePickerView //your text field

  //I add a toolBar to the datePicker

  let pickerToolBar = UIToolbar()
  pickerToolBar.barStyle = UIBarStyle.BlackOpaque //you can change the style
  pickerToolBar.translucent = true
  pickerToolBar.tintColor = UIColor.redColor() // or other colours
  pickerToolBar.sizeToFit()

  let spaceButtonPicker = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
  let cancelButtonPicker = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Plain, target: self, action: "cancelDatePicker:")
  pickerToolBar.setItems([cancelButtonPicker, spaceButtonPicker], animated: false)
  pickerToolBar.userInteractionEnabled = true
   tfDateNaissance.inputAccessoryView = pickerToolBar

}



func datePickerValueChanged(sender: UIDatePicker) {

 let dateFormatter = NSDateFormatter()
 dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
 dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
 tfDateNaissance.text = dateFormatter.stringFromDate(sender.date)
 //if you leave resignFirstResponder() here, the picker will close as soon as the value change

}

this handle the done button

func cancelDatePicker(sender: UIBarButtonItem){
  tfDateNaissance.resignFirstResponder()
}

this will be the result

enter image description here

Mat
  • 6,236
  • 9
  • 42
  • 55
0

it's me again.

For Q1, What is the event for tfDateNaissanceEditing function you're listening? What's your purpose for tfDateNaissance.resignFirstResponder()? I guess what happened there is that you listen the startEditing event. So the date picker is set as input view the first time you touch it, and immediately is recalled by the last line of code.

Theoretically, you could achieve what you want by just have some code like the following in viewDidLoad

...
// your other functions

let datePickerView : UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
UITextField.inputView = datePickerView

datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)

Q2. Currently every time the value of the DatePicker changes, it will resign itself, so remove tfDateNaissance.resignFirstResponder() in datePickerValueChanged function will solve the problem. If you want to have a custom toolbar with done button, you can manually create one and set it as input accessory view also in viewDidLoad. You may also achieve this by using navigation bar like this answer

BTW, didReceiveMemoryWarning function is not needed for this question.

Community
  • 1
  • 1
zc246
  • 1,514
  • 16
  • 28
  • Also forgetter that line: `dateFormatter.dateFormat = "dd-MMM-yyyy"` doesn't work – Ben Dec 23 '15 at 10:59
  • @Ben, Date format for the `UIDatePicker` is locale dependent. So if you want some custom format, you need to implement your own `UIPickerView` – zc246 Dec 23 '15 at 11:01
  • No it's ok it was because of `dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle` – Ben Dec 23 '15 at 11:02
0

First of all use delegate callback methods for the uitextfield. Present the date picker (usually done modally) in the

textFieldDidBeginEditing:

In the modal view controller add a done button which dismisses the modal view controller. also take the date values set in the date picker and put them in the text view by something like:

[self.PresentingViewController (your function)];

Shubham Chawla
  • 132
  • 1
  • 10