Search code examples
iosswiftuidatepicker

uidatepicker always rolls to current time


enter image description here enter image description here

Datepicker always scrolls to current time once the button is pressed, and also datepicker time does not get displayed.

I am setting up a datepicker. I am trying to connect datepicker and button to label to show correct time. I have connected a "PickUp ASAP" Button to " @IBAction func buttonPressed" as shown in code ahead, which works fine i.e shows current date and time in the "Label" when pressed (here it is 2019 11 06 04:20: PM) (see images above and code below). So, it is all fine here.

Now, I have also tried to connect the "@IBAction func datePickerChanged" to show current date and time of the in the "Label"when scrolled(see images above and code below).

  1. My main problem is that once I press the "PickUP ASAP" Button, no matter what I do, the datepicker always scrolls back to current date and time. Even if I scroll the datepicker to a different date, it always scrolls back to current date and time.

  2. Another problem is that "Label" does not show any date and time of the datepicker, if I scroll the datepicker without clicking the "Pickup ASAP" button. I want the "Label" to show the date and time of the datepicker when scrolled.

Also, the format of display in the "Label" when I press either "Pickup ASAP" button or scroll the datepicker should be the same.

I am attaching necessary screenshots of simulator as well as storyboard respectively above.

     import UIKit

     @IBDesignable class testdateViewController: UIViewController {

     @IBOutlet weak var Label: UILabel!

     @IBOutlet weak var picker: UIDatePicker!

     @IBAction func buttonPressed(_ sender: UIButton) {

      picker.addTarget(self, action: #selector(buttonPressed), for: .valueChanged)
      let currentDateTime = Date()

      let formatter = DateFormatter()

      formatter.dateFormat = "yyyy MM dd hh:mm:  a"

      Label.text = " \( (formatter.string(from: currentDateTime)))"

      picker.date =  currentDateTime
    }

      override func viewDidLoad() {
       super.viewDidLoad()

     let datepicker = UIDatePicker()

     datepicker.addTarget(self, action: #selector(testdateViewController.datePickerChanged), for: UIControl.Event.valueChanged)
     }

     @IBAction func datePickerChanged(_ sender: Any) {

     let datePicker = UIDatePicker()
     let dateFormatter = DateFormatter()
     let strDate = dateFormatter.string(from: datePicker.date)
     Label.text = strDate
     }

     override func didReceiveMemoryWarning() {
     super.didReceiveMemoryWarning()
     // Dispose of any resources that can be recreated.
       }
     }

Solution

  • Code Update:

    Remove this code from ViewDidLoad()

    let datepicker = UIDatePicker()
    datepicker.addTarget(self, action: #selector(testdateViewController.datePickerChanged), for: UIControl.Event.valueChanged)
    

    and use this in ViewDidLoad()

     picker.addTarget(self, action: #selector(testdateViewController.datePickerChanged), for: UIControl.Event.valueChanged)
    

    Move some code from buttonPressed method to datePickerChanged.

    datePickerChanged will look like

    @IBAction func datePickerChanged(_ sender: Any) {
         updateData(date: picker.date) 
     } 
    

    If you want to show current date in the label then you can manager another method to set the value to the label like this

    func updateData(date: Date) {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy MM dd hh:mm:  a"
        let strDate = dateFormatter.string(from: picker.date)
        Label.text = strDate
    }
    

    And in ViewDidLoad() method add this

     updateData(date: Date()) // This will show the current date value
    

    In final ViewDidLoad() will look like

    override func viewDidLoad() {
       super.viewDidLoad() 
       picker.date =  Date() // You can set any date initially that you want. This will be a date object 
       picker.addTarget(self, action: #selector(testdateViewController.datePickerChanged), for: UIControl.Event.valueChanged)
       updateData(date: Date())
     }
    

    And also remove all the code from buttonPressed. Because during the initial load it will show the current time on the label.

    The full code will look like

    import UIKit
    
    class testdateViewController: UIViewController {
    
        @IBOutlet weak var Label: UILabel!
        @IBOutlet weak var picker: UIDatePicker!
        @IBAction func buttonPressed(_ sender: UIButton) {
    
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
            picker.date =  Date() // You can set any date initially that you want. This will be a date object
            picker.addTarget(self, action: #selector(testdateViewController.datePickerChanged), for: UIControl.Event.valueChanged)
            updateData(date: Date())
    
        }
    
        @IBAction func datePickerChanged(_ sender: Any) {
           updateData(date: picker.date)
        }
    
        func updateData(date: Date) {
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "yyyy MM dd hh:mm:  a"
            let strDate = dateFormatter.string(from: picker.date)
            Label.text = strDate
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }