39

I have just started using UIDatePicker in my iPad app, but is there a way of checking when the date has been changed?

I want to do something when the date is changed. What can I try?

halfer
  • 19,824
  • 17
  • 99
  • 186
Josh Kahane
  • 16,765
  • 45
  • 140
  • 253

4 Answers4

84

When properly configured, a UIDatePicker object sends an action message when a user finishes rotating one of the wheels to change the date or time; the associated control event is UIControlEventValueChanged.

so you need to add your class to handle UIControlEventValueChanged event in your picker:

[picker addTarget:self action:@selector(dateChanged:) 
              forControlEvents:UIControlEventValueChanged];
...

- (void) dateChanged:(id)sender{
   // handle date changes
}
Vladimir
  • 170,431
  • 36
  • 387
  • 313
  • It's worth noting that the `:(id)sender` part is essential for the `dateChanged` function to work. You will get errors without it. –  Jan 22 '12 at 11:10
  • 2
    @Chimp I don't see that the :(id)sender is actually needed, at least not on iOS 5. Perhaps check that your declaration matches your implementation. – Micah Hainline May 23 '12 at 14:02
  • :(id)sender isn't "necessary" per se, but it's a useful convention that is used throughout iOS SDK. If you do not want :(id)sender following the method, do this: [picker addTarget:self action:@selector(dateChange) forControlEvents:UIControlEventValueChanged]; – Ben Dec 03 '13 at 07:53
29

Swift 4 version:

UIDatePicker Setup:

let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
dateTextField.inputView = datePicker
datePicker.addTarget(self, action: #selector(datePickerChanged(picker:)), for: .valueChanged)

Function:

@objc func datePickerChanged(picker: UIDatePicker) {
    print(picker.date)
}

If you notice, Swift 4 requires @objc in the function if you're going to use #selector()

yoAlex5
  • 29,217
  • 8
  • 193
  • 205
John Riselvato
  • 12,854
  • 5
  • 62
  • 89
4

swift version

override func viewDidLoad() {
    super.viewDidLoad()
    let picker = UIDatePicker(frame: CGRectMake(0, 0, 200, 200))
    picker.addTarget(self, action: #selector(datePickerChanged(picker:)), for: .valueChanged)
    view.addSubview(picker)
}

@objc func datePickerChanged(picker: UIDatePicker) {
    print(picker.date)
}
MobileMon
  • 8,341
  • 5
  • 56
  • 75
ethanneff
  • 3,083
  • 5
  • 23
  • 15
1

Swift 3 version:

override func viewDidLoad() {
    super.viewDidLoad()

    if sYourSelectedDate == "" {
        if let plist = Plist(name: "YourPlistName") {
            sYourSelectedDate = plist.getSingleValueInPlistFile(sFieldName: "yourSelectedDate")!

        }
    }
    if sYourSelectedDateTime == "" {
        if let plist = Plist(name: "YourPlistName") {
            sYourSelectedDateTime = plist.getSingleValueInPlistFile(sFieldName: "yourSelectedDateTime")!

        }
    }

    // add dateTimePickerChanged event (e.g., if device is powered down, values get saved)
    self.dateTimePicker.addTarget(self, action: #selector(dateTimeChanged), for: .valueChanged);

    // set min and max dates of datetimePicker
    // subtracting 1 minute from current time
    let currentTempDate = NSDate()
    let newDate = currentTempDate.addingTimeInterval(-1 * 60);
    let currentDate = newDate;

    let calendar: NSCalendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)!

    calendar.timeZone = NSTimeZone(name: "US/Eastern")! as TimeZone

    let components: NSDateComponents = NSDateComponents()
    components.calendar = calendar as Calendar

    components.year = -1
    let minDate: NSDate = calendar.date(byAdding: components as DateComponents, to: currentDate as Date, options: NSCalendar.Options(rawValue: 0))! as NSDate

    let maxDate: NSDate = currentDate as NSDate

    self.dateTimePicker.minimumDate = minDate as Date
    self.dateTimePicker.maximumDate = maxDate as Date

    //print("minDate: \(minDate)")
    //print("maxDate: \(maxDate)")

    if(sYourSelectedDateTime == "")
    {
        // subtracting 1 minute from current time
        let currentTempDate = NSDate()
        let newDate = currentTempDate.addingTimeInterval(-1 * 60);
        let currentDate2 = newDate;

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat =  "MM/dd/yyyy h:mm a"

        calendar.timeZone = NSTimeZone(name: "US/Eastern")! as TimeZone

        let userCalendar = Calendar.current
        let requestedComponents: Set<Calendar.Component> = [
            .year,
            .month,
            .day,
            .hour,
            .minute
        ]

        let dateTimeComponents = userCalendar.dateComponents(requestedComponents, from: currentDate2 as Date)

        let iPhoneDateComponents = NSDateComponents()
        iPhoneDateComponents.year = dateTimeComponents.year!;
        iPhoneDateComponents.month = dateTimeComponents.month!;
        iPhoneDateComponents.day = dateTimeComponents.day!;
        iPhoneDateComponents.hour = dateTimeComponents.hour!;
        iPhoneDateComponents.minute = dateTimeComponents.minute!;
        iPhoneDateComponents.timeZone = NSTimeZone(name: "US/Eastern") as TimeZone?

        let iPhoneDate = calendar.date(from: iPhoneDateComponents as DateComponents)!

        self.dateTimePicker.date = iPhoneDate;
        sYourInitialDateTime = dateFormatter.string(from: self.dateTimePicker.date);

        if let plist = Plist(name: "YourPlistFile") {
            plist.editSingleValueInPlistFile(dictString: "YourPlistFile", sFieldName: "yourInitialDateTime", sValue: sYourInitialDateTime)
        }

    } else {
        let dateFormatter: DateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MM/dd/yyyy h:mm a"
        let dateObj = dateFormatter.date(from: sYourSelectedDateTime)
        self.dateTimePicker.date = dateObj!
    }

}

func dateTimeChanged(picker: UIDatePicker) {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat =  "MM/dd/yyyy"
    sYourSelectedDate = dateFormatter.string(from: picker.date);
    dateFormatter.dateFormat =  "MM/dd/yyyy h:mm a"

    sYourSelectedDateTime = dateFormatter.string(from: picker.date);

    if (sYourSelectedDateTime == sYourInitialDateTime)
    {
        sYourSelectedDate = "";
        sYourSelectedDateTime = "";
    }

    if let plist = Plist(name: "YourPlistFile") {
        plist.editSingleValueInPlistFile(dictString: "YourPlistName", sFieldName: "yourSelectedDate", sValue: sYourSelectedDate)
        plist.editSingleValueInPlistFile(dictString: "YourPlistName", sFieldName: "yourSelectedDateTime", sValue: sYourSelectedDateTime)

    } else {
        print("Unable to get Plist")
    }
    print(sYourSelectedDate);
    print(sYourSelectedDateTime);

}
  • 1
    This doesn't seem to work if you click done to set the default value. I have to scroll to a different value and scroll back to the default then click done. Any ideas? – Ryan Jun 22 '17 at 00:11
  • Ryan, I am only saving values selected in the UIDatePicker to a Plist file upon each selection so if application is shut down on any form or shut down the value last selected can be reloaded when the program is started again. Not saving value only in the picker. The data lives on that way past the control. There is no button if picker is dragged from controls to form. –  Jun 29 '17 at 17:48