Reputation: 6396
I came across a situation where I needed to restrict a UIDatePicker
's selected hour, but still allow free selection of the day. This would be useful if you wanted to allow a user to select a date/time during set business hours. I found something that was close to what I was wanting to do by alerting the user that their selection was bad, but didn't actually change the date on the picker, so I wanted to share my solution Q&A-style.
Upvotes: 3
Views: 4311
Reputation: 1
In Swift 4:
func datePickerChanged() {
var components = Calendar.current.dateComponents([.hour, .minute, .month, .year, .day], from: datePicker.date)
if components.hour! < 7 {
components.hour = 7
components.minute = 0
datePicker.setDate(Calendar.current.date(from: components)!, animated: true)
}
else if components.hour! > 21 {
components.hour = 21
components.minute = 59
datePicker.setDate(Calendar.current.date(from: components)!, animated: true)
}
else {
print("Everything is fine!")
}
}
Upvotes: 0
Reputation: 1552
If you want to actually limit the hours that are displayed, I built a custom picker for that purpose. It's a subclass of UIPickerView
and it replicates the functionality of UIDatePicker in countDownTimer mode, while adding support to set maxTimeInterval
.
You use it like this:
GSTimeIntervalPicker *picker = [[GSTimeIntervalPicker alloc] init];
picker.maxTimeInterval = (3600 * 3); // set the limit
picker.minuteInterval = 5; // the step. Default is 1 min.
picker.timeInterval = (3600 * 1.5); // 1 h 30 minutes
picker.onTimeIntervalChanged = ^(NSTimeInterval newTimeInterval) {
// Use the value
};
Available on GitHub under MIT license. Blog post here.
Upvotes: 1
Reputation: 5655
In Swift2.0:
func datePickerChanged() {
let components = NSCalendar.currentCalendar().components(
[NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day, NSCalendarUnit.WeekOfYear, NSCalendarUnit.Hour, NSCalendarUnit.Minute, NSCalendarUnit.Second, NSCalendarUnit.Weekday, NSCalendarUnit.WeekdayOrdinal, NSCalendarUnit.WeekOfYear],
fromDate: datePickerInstance.date)
if components.hour < 7 {
components.hour = 7
components.minute = 0
datePickerInstance.setDate(NSCalendar.currentCalendar().dateFromComponents(components)!, animated: true)
}
else if components.hour > 21 {
components.hour = 21
components.minute = 59
datePickerInstance.setDate(NSCalendar.currentCalendar().dateFromComponents(components)!, animated: true)
}
else {
print("Everything is good.")
}
}
Upvotes: 2
Reputation: 6396
This particular example will not allow selection of times before 7:00am or after 9:59pm. Selection of an "invalid" time will immediately slide the UIDatePicker
back to the closest valid time on the respective end of the spectrum (for example, selection of 10:02pm will immediately slide back to 9:59pm)
- (void)datePickerChanged
{
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit fromDate:datePicker.date];
if([components hour] < 7)
{
[components setHour:7];
[components setMinute:0];
[datePicker setDate:[[NSCalendar currentCalendar] dateFromComponents:components]];
}
else if([components hour] > 21)
{
[components setHour:21];
[components setMinute:59];
[datePicker setDate:[[NSCalendar currentCalendar] dateFromComponents:components]];
}
}
Edit: As @DuncanC suggested in the comments, feedback to the user should probably be included, such as a label saying "Only times between 7:00am and 9:59pm can be used"
Upvotes: 5