0

How can I load data into a pickerdate from mysql?

As it is now, I can load the correct data on each text filed. The problem is: the uidatepicker remembers only 1 value and it doesnt load the other one.

In the picture I show that when clicked on Date of Issue text field, it shows the value of Due Date on the pickerView. The correct should be: December 25 2000

enter image description here

Milan helped me on the creation of selecting a date, using the same function ==> link to the question

View Controller

import UIKit
class InvoiceViewController: UIViewController, AccessoryToolbarDelegate {

var thePicker = UIDatePicker()

@IBOutlet weak var dateIssueTextField: UITextField!
@IBOutlet weak var dueDateTextField: UITextField!

func doneClicked(for textField: UITextField) {
    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .short
    dateFormatter.timeStyle = .none

    //show on text field
    dateFormatter.dateFormat = "dd MMM yyyy"
    textField.text = dateFormatter.string(from: thePicker.date)

    //formated to store on mysql
    dateFormatter.dateFormat = "yyyy-MM-dd"
    let finalDate: String = dateFormatter.string(from: thePicker.date)
    print(finalDate)
    textField.resignFirstResponder()
}

func cancelClicked(for textField: UITextField) {
    textField.resignFirstResponder()
}

func setUpTextFieldPicker(textField: UITextField, date: String) {

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat =  "yyyy-MM-dd"

    if let fullDate = dateFormatter.date(from: date) {
        thePicker.date = fullDate
        dateFormatter.dateFormat = "dd MMM yyyy"
        let finalDate: String = dateFormatter.string(from: fullDate)
        textField.text = finalDate
    }


    textField.inputView = thePicker
    let toolbar = AccessoryToolbar(for: textField)
    toolbar.accessoryDelegate = self
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.thePicker = UIDatePicker(frame:CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 216))
    self.thePicker.backgroundColor = UIColor.white
    self.thePicker.datePickerMode = UIDatePickerMode.date

    //data will be loaded from an API to a server. Hard Coded now just for testing
    setUpTextFieldPicker(textField: dateIssueTextField, date:"2000-12-25" )
    setUpTextFieldPicker(textField: dueDateTextField, date:"2010-05-03")
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
}
}

Helper Class

import UIKit

protocol AccessoryToolbarDelegate: class {
func doneClicked(for textField: UITextField)
func cancelClicked(for textField: UITextField)
}

class AccessoryToolbar: UIToolbar {

fileprivate let textField: UITextField

weak var accessoryDelegate: AccessoryToolbarDelegate?

init(for textField: UITextField) {
    self.textField = textField
    super.init(frame: CGRect.zero)

    self.barStyle = .default
    self.isTranslucent = true
    self.tintColor = UIColor(red: 92/255, green: 216/255, blue: 255/255, alpha: 1)
    self.sizeToFit()

    let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneClicked))
    let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelClicked))
    self.setItems([cancelButton, spaceButton, doneButton], animated: false)
    self.isUserInteractionEnabled = true

    textField.inputAccessoryView = self
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

@objc fileprivate func doneClicked() {
    accessoryDelegate?.doneClicked(for: self.textField)
}

@objc fileprivate func cancelClicked() {
    accessoryDelegate?.cancelClicked(for: self.textField)
}
}

small note: I think the data should be read and assigned on viewWillAppear.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Renan Aguiar
  • 245
  • 5
  • 22

1 Answers1

1

You can fix the problem by two ways:

  1. Create two Date objects for each text field, and update new value for that object when you hit Done button. Update the date picker value based on that date when the text field becomes the first responder.
  2. Update the date picker value when text field becomes the first responder, you can check this code:

    //1. Add UITextFieldDelegate
    class InvoiceViewController: UIViewController, AccessoryToolbarDelegate, UITextFieldDelegate {
         //......
    
    //2. Set delegate for the textfields
    override func viewDidLoad() {
        super.viewDidLoad()
    
        dateIssueTextField.delegate = self
        dueDateTextField.delegate = self
    
        //......
    }
    
    //3. Update the value of thePicker.date
    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat =  "yyyy-MM-dd"
    
        if let fullDate = dateFormatter.date(from: textField.text) {
            thePicker.date = fullDate
        }
    
        return true
    }
    }
    
Tony TRAN
  • 2,118
  • 1
  • 15
  • 16
  • solution 2 didnt work. Solution 1, Im not sure if I understand – Renan Aguiar Feb 22 '18 at 05:55
  • Both actually the same, for the solution1 you define 2 Date() objects to store the value of selected thePicker.date instead of using String(). You should check to make sure the textfield.delegate not nil. And also set a breakpoint to check if the method textFieldShouldBeginEditing are calling when you tap on the text field. – Tony TRAN Feb 22 '18 at 07:54
  • Thanks, I did some changes. The great 'tip' was textFieldShouldBeginEditing. I moved the loading data from viewDidLoad to viewWillAppear => dueDateTextField.text = "03 Mar 2001" and removed all lines of setUpTextFieldPicker but the last 3. – Renan Aguiar Feb 22 '18 at 13:58