Search code examples
iosobjective-cuitableviewdateuidatepicker

Setting a minimum and maximum month in iOS date picker, but should update the picker view


When you select the date field in a view, the date picker displays. I want to limit the scroll from a minimum 2 months less than current month and a maximum 4 months more than current month. I have seen similar examples. For example: for current month November, the month range should be September - March next year.

I tested this example, but wasn't successful.

// Configure date picker
- (void) initializeDatePicker {
    _datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 0, 600, 160)];
    _datePicker.backgroundColor = [UIColor whiteColor];
    _datePicker.datePickerMode = UIDatePickerModeDate;
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDate *currentDate = [NSDate date];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setMonth:-2];
NSDate *minDate = [gregorian dateByAddingComponents:comps toDate:currentDate  options:0];
[comps setMonth:4];
NSDate *maxDate = [gregorian dateByAddingComponents:comps toDate:currentDate  options:0];

_datePicker.minimumDate = minDate;
_datePicker.maximumDate = maxDate;


[_datePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
[_txfDateTextField setInputView:_datePicker];
selectedDate =[NSDate date];
}

UPDATE: The above code updates the date picker object. However, the problem is that there is no change in the date picker view. For the example above, I want the scroll to limit scrolling from September to March next year. This way the user doesn't get overwhelmed when he is scrolling. From a better UX point of view.


Solution

  • Ok, based on an extended discussion, I now understand that the goal is to remove months that are outside of the range.

    You can't do it with a standard date picker. You would have to build a custom control using a UIPickerView.

    The short answer is, "Don't do that."

    If you want to allow 2 months back, and 4 months forward:

    If your current date is November, 2016:

    Valid months are September, October, November 2016, December 2016, and January, February, and March 2017.

    So if the user selects 2016, you'd need to populate the month picker wheel with September, October, November. Then if the user switches to 2017, you'd need to rebuild the month wheel with only January, February, and March.

    But, now you're not using a date picker, you're using a UIPickerViewthat you want to act like a date picker.

    So in addition to rebuilding the month spinner based on the current year, you have to manage setting up the day picker to show the valid days for the currently selected year and month. Most months have 30 or 31 days, but what about February? What about leap years? What about centuries, which aren't leap years?

    Plus, you're building a control that looks like a date picker, and sort of, but not quite, acts like a date picker.

    Are you going handle calendars other than Gregorian? What about Hebrew, Arabic, Chinese calendars? The burden is on you to make all of that work correctly.

    Apple has spent a LOT of money on usability studies and come up with a standard control that works well, and does handle localization for different calendar systems, etc, etc.

    In short, this is a rabbit hole you do not want to descend into.