0

I try to use this code to get date picker when clicking on a text field:

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 = .none
        dateFormatter.timeStyle = .short
        dateFormatter.locale = Locale.init(identifier: "it_IT")
        self.DOBTextField.text = dateFormatter.string(from: datePicker.date)
    }
    self.DOBTextField.resignFirstResponder()
 }
}


 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 = .time
    datePicker.locale = Locale.init(identifier: "it_IT")
    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()
   }
}

But when I click on text field again, time on date picker move forward on 3 dimensions. How this can be fixed? I want time on date picker to rest the same as it is on text field.

enter image description here

I try to implement this code, but it crash:

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var DOBTextField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()

    DOBTextField.addInputViewDatePicker(target: self, selector: #selector(doneButtonPressed), textFieldText: DOBTextField.text ?? "")
}

@objc func doneButtonPressed() {
    if let  datePicker = self.DOBTextField.inputView as? UIDatePicker {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .none
        dateFormatter.timeStyle = .short
        dateFormatter.locale = Locale.init(identifier: "it_IT")
        self.DOBTextField.text = dateFormatter.string(from: datePicker.date)
    }
    self.DOBTextField.resignFirstResponder()
 }
}


 extension UITextField {

   func addInputViewDatePicker(target: Any, selector: Selector , textFieldText: String?) {


    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 = .time
    datePicker.locale = Locale.init(identifier: "it_IT")
    self.inputView = datePicker

    if textFieldText != nil {
        /// Set Textfield date & time
          let dateFormatter = DateFormatter()
          dateFormatter.dateStyle = .none
          dateFormatter.timeStyle = .short
          dateFormatter.locale = Locale.init(identifier: "it_IT")
          datePicker.date = dateFormatter.date(from: textFieldText!)!
      }
     else {
      /// set current date & time
      datePicker.date = Date()
    }


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

How this can be fixed?

ucelme
  • 97
  • 1
  • 13
  • remove UITextField storyboard after add UITextField – Tanjima Kothiya Dec 17 '19 at 11:04
  • Remove UITextField storyboard after add UITextField? Can you explain more, what exactly do you mean? I don't understand. – ucelme Dec 17 '19 at 11:07
  • your code is perfect work . UITextField storyboard connection problem you one time UITextField remove and add UITextField – Tanjima Kothiya Dec 17 '19 at 11:13
  • I tried to delete UITextField connection with Storyboard and then add it again. But it didn't help. I even tried to create completely new project, but it doesn't work either. – ucelme Dec 17 '19 at 11:18

2 Answers2

1

As per I understand, You want to textfield's time when datepicker opens. You just have to set date for DatePicker when it will be initialized.

Set DatePicker's date :

extension UITextField {

func addInputViewDatePicker(target: Any, selector: Selector , textFieldText:String?) {


//Add DatePicker as inputView

//Set date for date Picker
  if textFieldText != nil {
      /// Set Textfield date & time
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .none
        dateFormatter.timeStyle = .short
        dateFormatter.locale = Locale.init(identifier: "it_IT")
        datePicker.date = dateFormatter.date(from: textFieldText!)!
    }
   else {
    /// set current date & time
    datePicker.date = Date()
  }

     //Add Tool Bar as input AccessoryView
  }
}

Change in your viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()

    DOBTextField.addInputViewDatePicker(target: self, selector: #selector(doneButtonPressed), textFieldText: DOBTextField.text ?? "")
}

I hope you understand what you have to set with datepicker. If this code is not working as you want then take Action of textfield (Editing Did Begin) & try to set textfield inputView in Action.

Abhishek Patel
  • 121
  • 1
  • 1
  • 11
0

It seems this problem only appears on simulators. When I try to test this code on real device everything works fine. May be it's just Xcode bug.

ucelme
  • 97
  • 1
  • 13
  • did you check my answer? – Abhishek Patel Dec 18 '19 at 04:52
  • Yes. But it crashes: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value – ucelme Dec 18 '19 at 09:22
  • I added the full code with your solution to my question. – ucelme Dec 18 '19 at 12:03
  • Can you please check with this code in your extension `if let nsdate = dateFormatter.date(from: textFieldText!) { datePicker.date = nsdate; } else { print("There is issue in dateformatter. Not able to convert string to NSDate ") }` – Abhishek Patel Dec 18 '19 at 12:16
  • There is issue in dateformatter. Not able to convert string to NSDate – ucelme Dec 18 '19 at 12:35
  • then check your datepicker formate throughout the project. Debug your code & check what you get in the string (textFieldText). I don't know which dateformater you are using. I just give you a conceptual idea that can help you but you have to debug code & check all values. Please don't copy paste my answer (code) until you don't know where it will impact in your project. – Abhishek Patel Dec 18 '19 at 12:44
  • I created another question with this issue - https://stackoverflow.com/questions/59392923/cannot-convert-string-to-date-for-datepicker. I don't understand why this code doesn't work. – ucelme Dec 18 '19 at 13:20
  • Please tick my answer for this question. I will reply to you on your another question. – Abhishek Patel Dec 18 '19 at 13:22
  • It is working for this question but you changed (Edit) whole question. I am using this code in many places but there is an issue in your dateformatter . So you don't debug your code? Right . – Abhishek Patel Dec 19 '19 at 04:24