Agung
Agung

Reputation: 13803

How to set the minimum date properly and to get the minimum date that displayed on picker view?

enter image description here

I have a pop up view controller like the picture above. In viewDidLoad, I set the minimum date for picker view is now ( Date() ), and in storyboard, I set the interval time in 15 minutes. here is the code I use

class DateTimePickerVC: UIViewController {


    @IBOutlet var dateTimePickerView: UIDatePicker!

    var selectedDateAndTime : Date?

    override func viewDidLoad() {
        super.viewDidLoad()

        // to make live update of selected date
        dateTimePickerView.addTarget(self, action: #selector(DateTimePickerVC.datePickerValueChanged), for: UIControl.Event.valueChanged)

        // minimum date is now
        dateTimePickerView.minimumDate = Date()

        // set initial value, to avoid nil value
        selectedDateAndTime = dateTimePickerView.date


    }

    @objc func datePickerValueChanged (datePicker: UIDatePicker) {
        selectedDateAndTime = datePicker.date
    }



    @IBAction func pickedButtonDidPressed(_ sender: Any) {
        // send date 'selectedDateAndTime' to other VC
    }

}

I have 2 problems in here:

  1. let say the user open that pop up datePickerVC at 16:28. I expect the minimum date and time that will be displayed at that pop up will be "Today 16:30", but at my case is "Today 16:15". how to solve this issue?

  2. to avoid nil value of selectedDateAndTime , in viewDidLoad I set selectedDateAndTime = dateTimePickerView.date, so I hope that when the user immediately tap the save button and send the date to other VC without scrolling the date picker, it will get the minimum date that displayed in datePicker. let say the user open that pop up at 16:08, I expect the selected date to be the minimum date and time displayed at datePickerView (today 16:15), but the actual date value I get is (Today 16:08), because I set the datePicker.minimumDate = Date() (now). how to get the minimum date that displayed on datePicker view ?

Upvotes: 1

Views: 745

Answers (2)

Sujit Nachan
Sujit Nachan

Reputation: 204

enum DateRoundingType {
    case round
    case ceil
    case floor
}


extension Date {
    func rounded(minutes: TimeInterval, rounding: DateRoundingType = .round) -> Date {
        return rounded(seconds: minutes * 60, rounding: rounding)
    }
    func rounded(seconds: TimeInterval, rounding: DateRoundingType = .round) -> Date {
        var roundedInterval: TimeInterval = 0
        switch rounding  {
        case .round:
            roundedInterval = (timeIntervalSinceReferenceDate / seconds).rounded() * seconds
        case .ceil:
            roundedInterval = ceil(timeIntervalSinceReferenceDate / seconds) * seconds
        case .floor:
            roundedInterval = floor(timeIntervalSinceReferenceDate / seconds) * seconds
        }
        return Date(timeIntervalSinceReferenceDate: roundedInterval)
    }
}

Usage:

//add below code in viewDidLoad()
let nextMinuteIntervalDate = Date().rounded(
    minutes: 15,
    rounding: .ceil
)
dateTimePickerView.minimumDate = nextMinuteIntervalDate
dateTimePickerView.setDate(nextMinuteIntervalDate, animated: true)

Upvotes: 2

Shubham Bakshi
Shubham Bakshi

Reputation: 572

  1. I think you must be aware of the fact that why it is showing 16:15 as the time (16:28) is still logically less than 16:30 and I don't think you can do that as it doesn't make any logical sense

  2. By the declaration of minimumDate :

var minimumDate: Date? { get set }

As minimumDate has a get property, you can just fetch the minimum date using :

// Since it is an optional , we have to safe unwrap it 
if let minimumDate = datePicker.minimumDate {
   // Use your minimumDate variable here
} 

Upvotes: 1

Related Questions