Chris
Chris

Reputation: 53

How to make UIDatePicker update textfield and database in Swift 4

In my app I have a form that has a textField that pulls up a UIDatePicker when clicked. When I select a new date from the UIDatePicker the textField does not update.

When debugging it seems like when a new date is selected the action isn't registered and it just sends over the same date.

Below is my code (Which I am planning on refactoring/cleaning up after resolving this issue)

import UIKit
import RealmSwift

class ClientDetailsViewController: UIViewController, UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource {
    let realm = try! Realm()

    //Create Picker Views

    let dateAppointedPickerView = UIDatePicker()

    @IBOutlet weak var clientDateAppointedText: UITextField!


    var selectedClient : Client? {
        //Everything in the did set function will happen as soon as this variable is set with a value
        didSet {
            loadClientDetails()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        //Assign Picker Views
        setPickerViews()

        //Assign Picker View Settings
        setPickerViewSettings()

        //Assign Picker View Delegates
        setDelegates()
    }

    //MARK: - Date Format Method

    func formatDateToString(_ date: Date) -> String {

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MMMM dd, yyyy"
        dateFormatter.locale = Locale.current
        let formattedDate = dateFormatter.string(from: date)

        return formattedDate
    }

    func formatStringToDate(_ dateString: String) -> Date {

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MMMM dd, yyyy"
        dateFormatter.locale = Locale.current
        let formattedDate = dateFormatter.date(from: dateString)

        return formattedDate!
    }

    func loadClientDetails() {
        loadViewIfNeeded()

        clientDateAppointedText.text = formatDateToString((selectedClient?.dateAppointed)!)

    }

    //Send textfield/picker data to database
    func textFieldDidEndEditing(_ textField: UITextField) {
        var clientData : String = ""

        guard let currentClient = selectedClient else {fatalError()}
        switch textField {

        case clientDateAppointedText:
            clientData = "clientDateAppointedText"
            updateClientDetails(currentClient, clientData)
        default:
            print("Did not edit anything")
        }
    }

    //MARK: - Data Manipulation Methods

    func updateClientDetails(_ clientInfo: Client,_ clientString: String) {

        let editClient : String = clientString
        do {
            try realm.write {
                switch editClient {

                case "clientDateAppointedText":
                    clientInfo.dateAppointed = formatStringToDate(clientDateAppointedText.text!)
                default:
                    print("Unable to edit client information")
                }
            }
        } catch {
            print("Unable to save client details")
        }
    }

I expect the Date Picker to update the textview every time a new date is chosen and for the value to be passed to the database to be updated. The actual result is that the value passed is the same date over and over again.

Upvotes: 0

Views: 1524

Answers (1)

Rajat Gupta
Rajat Gupta

Reputation: 120

Steps to do it:

  1. First intialize pickerview

     var datePickerView:UIDatePicker = UIDatePicker()
    
  2. Create action of textfield through storyboard i.e "Editing Did Begin"

    @IBAction func textEditing(_ sender: UITextField)
    {
       isPickUpSelected = true
       datePickerView = UIDatePicker()
       datePickerView.minimumDate = Date()
       datePickerView.date = selectedPickupDate
       datePickerView.datePickerMode = UIDatePickerMode.date
       sender.inputView = datePickerView
       datePickerView.addTarget(self, action: 
       #selector(TUGBestDealVC.datePickerValueChanged), for: 
       UIControlEvents.valueChanged)
       self.addToolBar(picker: datePickerView, textField: sender)
    }
    
  3. Write addToolbar function to customize datepicker:

    func addToolBar(picker: UIDatePicker, textField: UITextField) 
    {
       toolBar.barStyle = .default
       toolBar.isTranslucent = true
       toolBar.tintColor = UIColor.darkGray
       toolBar.sizeToFit()
       let doneButton = UIBarButtonItem(title: TUGHelpers().getLocalisedString(strKey: 
       "DONE"),style: .plain, target: self, 
       action:#selector(TUGBestDealVC.doneClick(sender:)))
       doneButton.tag = picker.tag
       let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: 
       nil,action: nil)
       let cancelButton = UIBarButtonItem(title:"Cancel", style: .plain, target: self, 
       action:#selector(TUGBestDealVC.cancelClick(sender:)))
       cancelButton.tag = picker.tag+4
       toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
       toolBar.isUserInteractionEnabled = true
       textField.inputAccessoryView = toolBar
    }
    
  4. Track action of datepicker change date:

    func datePickerValueChanged(sender:UIDatePicker)
    {
        self.setPickupDate(date: sender.date)     
    }
    
  5. Here is done action of datepickerview:

    @objc func doneClick(sender: UIButton)
    {
        self.setPickupDate(date: datePickerView.date)
        dateTxt.resignFirstResponder()
    }
    
  6. Here is cancel action of datepickerview:

    @objc func cancelClick(sender: UIButton) 
    {
         dateTxt.resignFirstResponder()
    }
    
  7. Here you will get the date of pickerview:

    func setPickupDate(date: Date)
    {
        print(date)
    }
    

The same code you can update in the database every time

Enjoy, Happy coding.

Upvotes: 2

Related Questions