Add ability to select a range of dates
Allows setting the selection mode of the calendar view to either allow selecting a single date or a range of dates. Delegate methods have been added for start and end date selection/dedeselection. Had already started working on this before I saw @kemeran's and @randomstep's pull requests, so their changes (ability to deselect a date and improved scrolling method) are also included.
I had the same need (selecting a date range), and ended up implementing a solution I wasn't quite satisfied with. This feature would probably be a worthy addition to TimesSquare.
@puls are there any specific design concerns or changes desired on this pull request? I am building out a calendar UI that requires mutli-date selection behaviors and would love to build against something that is destined for merge. I am happy to do any legwork to bring this PR up to code for a merge.
Needs a merge against master.
@puls see #33
Also needs a signed CLA from @mattgrayson.
CLA submitted
Couple of questions/comments on this:
- Why do we need a
selectedDateas well as astartDateandendDate. Couldn't we just flatten out the distinction such thatendDateis alwaysnilwhen you are in single date mode? - Why do we need
didDeselectdelegate methods? It seems likedidSelectDate:with anildate argument is sufficient. - I think that the selection configuration is better described as a 'mode' rather than a 'type':
typedef enum {
TSQCalendarSelectionModeDay = 0,
TSQCalendarSelectionModeDateRange = 1
} TSQCalendarSelectionMode;
Couple of other changes coming up on #33
Been a while since I looked at this, so my memory might be off:
- I think adding
startDate/endDatein addition toselectedDatewas to preserve compatibility with the existing API. - Makes sense
- Agree
Thanks for bringing up to date + fixes.
Updates pushed to #33 for items 2 and 3.
@puls Do you care about backward compatibility for the selectedDate property at the expense of the additional properties/delegate methods?
I don't care about backward compatibility so much as simplicity; it seems to me that being able to set a single selected date with a single method is a pretty common use case.
(For that matter, it seems like having a selection mode is pretty overkill, too; you should be able to make -setSelectedDate: just call both -setSelectedStartDate: and -setSelectedEndDate: with its argument.)
The selection mode determines the behavior taken when you touch on the calendar, i.e. touching another date when one is already selected when in day selection mode moves the date, but in date range selection mode it creates a range between the two dates.
Maybe I am missing something, but I don't see how you can get rid of that without moving the calendar to exclusively supporting ranged selections. For my use-case, I have a calendar for selecting flight departure/return dates. If you are searching for One Way flights you only want a single date selection, but for Round Trip you want a range. The user can toggle between these modes, which is currently modeled nicely by the selection mode.
Maybe we should punt on deciding what subsequent taps do; I can imagine a case where the first and second taps are relatively straightforward, but later ones are confusing.
Maybe a delegate callback: if the delegate doesn't respond, always select a single date; otherwise, do what the delegate says?