Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customise multiple selection #70

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions THCalendarDatePicker/THDateDay.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
@property (strong, nonatomic) UIColor *selectedBackgroundColor;
@property (strong, nonatomic) UIColor *currentDateColor;
@property (strong, nonatomic) UIColor *currentDateColorSelected;
@property (nonatomic, getter=isRounded) BOOL rounded;

- (IBAction)dateButtonTapped:(id)sender;

Expand Down
10 changes: 6 additions & 4 deletions THCalendarDatePicker/THDateDay.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ @implementation THDateDay
@synthesize selectedBackgroundColor = _selectedBackgroundColor;
@synthesize currentDateColor = _currentDateColor;
@synthesize currentDateColorSelected = _currentDateColorSelected;
@synthesize rounded = _rounded;

- (id)initWithFrame:(CGRect)frame
{
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code
_selectedBackgroundColor = [UIColor colorWithRed:89/255.0 green:118/255.0 blue:169/255.0 alpha:1];
_currentDateColor = [UIColor colorWithRed:242/255.0 green:121/255.0 blue:53/255.0 alpha:1.0];
_currentDateColorSelected = [UIColor whiteColor];
_rounded = NO;
}
return self;
}
Expand All @@ -38,8 +39,9 @@ - (void)drawRect:(CGRect)rect {

- (void)layoutSubviews {
[super layoutSubviews];
//might be #37
//[self addMaskToBounds:self.frame];
if ([self isRounded]) {
[self addMaskToBounds:self.frame];
}
}

#pragma mark -
Expand Down
8 changes: 8 additions & 0 deletions THCalendarDatePicker/THDatePickerViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
@property (strong, nonatomic) UIColor *currentDateColorSelected;
@property (nonatomic) float autoCloseCancelDelay;
@property (strong, nonatomic) NSTimeZone *dateTimeZone;
@property (nonatomic, getter=isRounded) BOOL rounded;
@property (weak, nonatomic) IBOutlet UIView *toolbarBackgroundView;
@property (nonatomic) float slideAnimationDuration;
@property (strong, nonatomic) NSArray * selectedDates;

- (void)setDateHasItemsCallback:(BOOL (^)(NSDate * date))callback;

Expand All @@ -47,6 +50,11 @@
*/
- (void)setAllowClearDate:(BOOL)allow;

/*! Enable Multi Day Selection
* \param allow selection of multiple days
*/
- (void)setAllowMultiDaySelection:(BOOL)allow;

/*! Enable Ok Button when selected Date has already been selected
* \param allow should show ok button
*/
Expand Down
164 changes: 150 additions & 14 deletions THCalendarDatePicker/THDatePickerViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ @interface THDatePickerViewController () {
NSUInteger _daysInFuture;
BOOL _disableYearSwitch;
BOOL (^_dateHasItemsCallback)(NSDate *);
float _slideAnimationDuration;
NSMutableArray * _selectedDates;
NSMutableArray * _selectedDateViews;
BOOL _allowMultiDaySelection;
BOOL _disableHistorySelection;
BOOL _disableFutureSelection;
}
@property (nonatomic, strong) NSDate * firstOfCurrentMonth;
@property (nonatomic, strong) THDateDay * currentDay;
Expand Down Expand Up @@ -62,6 +68,9 @@ @implementation THDatePickerViewController
@synthesize currentDateColorSelected = _currentDateColorSelected;
@synthesize autoCloseCancelDelay = _autoCloseCancelDelay;
@synthesize dateTimeZone = _dateTimeZone;
@synthesize rounded = _rounded;
@synthesize slideAnimationDuration = _slideAnimationDuration;
@synthesize selectedDates = _selectedDates;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
Expand All @@ -75,6 +84,12 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
_daysInHistory = NO;
_autoCloseCancelDelay = 1.0;
_dateTimeZone = [NSTimeZone defaultTimeZone];
_slideAnimationDuration = .5;
_disableFutureSelection = NO;
_disableHistorySelection = NO;
_selectedDates = [[NSMutableArray alloc] init];
_selectedDateViews = [[NSMutableArray alloc] init];
_allowMultiDaySelection = NO;
}
return self;
}
Expand All @@ -83,6 +98,10 @@ +(THDatePickerViewController *)datePicker {
return [[THDatePickerViewController alloc] initWithNibName:@"THDatePickerViewController" bundle:[NSBundle bundleForClass:self.class]];
}

-(void)setAllowMultiDaySelection:(BOOL)allow {
_allowMultiDaySelection = allow;
}

- (void)setAllowClearDate:(BOOL)allow {
_allowClearDate = allow;
}
Expand Down Expand Up @@ -258,7 +277,13 @@ - (void)redrawDays {
}

THDateDay * day = [[[NSBundle bundleForClass:self.class] loadNibNamed:@"THDateDay" owner:self options:nil] objectAtIndex:0];
day.frame = CGRectMake(curX, curY, cellWidth, cellHeight);
if ([self isRounded]) {
[day setRounded:YES];
// #37 still need to move the x/y coordinates apropriately
day.frame = CGRectMake(curX, curY, MIN(cellWidth, cellHeight), MIN(cellWidth, cellHeight));
} else {
day.frame = CGRectMake(curX, curY, cellWidth, cellHeight);
}
day.delegate = self;
day.date = [date dateByAddingTimeInterval:0];
if (self.currentDateColor)
Expand All @@ -268,6 +293,25 @@ - (void)redrawDays {
if (self.selectedBackgroundColor)
[day setSelectedBackgroundColor:self.selectedBackgroundColor];

if(!_allowMultiDaySelection)
{
if (_internalDate && ![[self dateWithOutTime:date] timeIntervalSinceDate:_internalDate]) {
self.currentDay = day;
[day setSelected:YES];
}
}
else
{
if ([_selectedDates containsObject:date])
{
[day setSelected:YES];
}
else
{
[day setSelected:NO];
}
}

[day setLightText:![self dateInCurrentMonth:date]];
[day setEnabled:![self dateInFutureAndShouldBeDisabled:date]];
[day indicateDayHasItems:(_dateHasItemsCallback && _dateHasItemsCallback(date))];
Expand All @@ -292,6 +336,7 @@ - (void)redrawWeekdays:(int)dayWidth {
int curX = (fullSize.width - 7*dayWidth)/2;
NSDateComponents * comps = [_calendar components:NSCalendarUnitDay fromDate:[NSDate date]];
NSCalendar *c = [NSCalendar currentCalendar];
[c setFirstWeekday:2];
[comps setDay:[c firstWeekday]-1];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
Expand All @@ -313,6 +358,25 @@ - (void)redrawWeekdays:(int)dayWidth {

#pragma mark - Date Set, etc.

- (NSArray *)selectedDates {
return [[NSArray alloc] initWithArray:_selectedDates];
}

- (void)setSelectedDates:(NSArray *)selectedDates {

_selectedDates = [[NSMutableArray alloc] init];
for (NSDate* selectedDate in selectedDates) {
[_selectedDates addObject:[self dateWithOutTime:selectedDate]];
}
if ([_selectedDates count] > 0)
{
_date = (NSDate*)[_selectedDates objectAtIndex:0];
_dateNoTime = !_date ? nil : [self dateWithOutTime:_date];
self.internalDate = [_dateNoTime dateByAddingTimeInterval:0];
}
[self redrawDays];
}

- (void)setDate:(NSDate *)date {
_date = date;
_dateNoTime = !date ? nil : [date dateWithOutTime];
Expand All @@ -335,6 +399,18 @@ - (NSDate *)date {
}

- (BOOL)shouldOkBeEnabled {
if (!_allowMultiDaySelection)
{
if (_autoCloseOnSelectDate)
return YES;
return (self.internalDate && _dateNoTime && (_allowSelectionOfSelectedDate || [self.internalDate timeIntervalSinceDate:_dateNoTime]))
|| (self.internalDate && !_dateNoTime)
|| (!self.internalDate && _dateNoTime);
}
else
{
return ([_selectedDates count] > 0);
}
if (_autoCloseOnSelectDate)
return YES;
return (self.internalDate && _dateNoTime && (_allowSelectionOfSelectedDate || [self.internalDate timeIntervalSinceDate:_dateNoTime]))
Expand Down Expand Up @@ -370,6 +446,7 @@ - (void)setDisplayedMonthFromDate:(NSDate *)date{
- (void)storeDateInformation{
NSDateComponents *comps = [_calendar components:NSCalendarUnitWeekday | NSCalendarUnitDay fromDate:self.firstOfCurrentMonth];
NSCalendar *c = [NSCalendar currentCalendar];
[c setFirstWeekday:2];
#ifdef DEBUG
//[c setFirstWeekday:FIRST_WEEKDAY];
#endif
Expand Down Expand Up @@ -410,21 +487,72 @@ - (BOOL)setDateTimeZoneWithName:(NSString *)name {
#pragma mark - User Events

- (void)dateDayTapped:(THDateDay *)dateDay {
if (!_internalDate || [_internalDate timeIntervalSinceDate:dateDay.date] || _allowSelectionOfSelectedDate) { // new date selected
[self.currentDay setSelected:NO];
[dateDay setSelected:YES];
BOOL dateInDifferentMonth = ![self dateInCurrentMonth:dateDay.date];
[self setInternalDate:dateDay.date];
[self setCurrentDay:dateDay];
if (dateInDifferentMonth) {
[self slideTransitionViewInDirection:[dateDay.date timeIntervalSinceDate:self.firstOfCurrentMonth]>0 ? UISwipeGestureRecognizerDirectionRight : UISwipeGestureRecognizerDirectionLeft];
if (!_allowMultiDaySelection)
{
if (!_internalDate || [_internalDate timeIntervalSinceDate:dateDay.date] || _allowSelectionOfSelectedDate) { // new date selected
[self.currentDay setSelected:NO];
[dateDay setSelected:YES];
BOOL dateInDifferentMonth = ![self dateInCurrentMonth:dateDay.date];
[self setInternalDate:dateDay.date];
[self setCurrentDay:dateDay];
if (dateInDifferentMonth) {
[self slideTransitionViewInDirection:[dateDay.date timeIntervalSinceDate:self.firstOfCurrentMonth]>0 ? UISwipeGestureRecognizerDirectionRight : UISwipeGestureRecognizerDirectionLeft];
}
if ([self.delegate respondsToSelector:@selector(datePicker:selectedDate:)]) {
[self.delegate datePicker:self selectedDate:dateDay.date];
}
if (_autoCloseOnSelectDate) {
[self.delegate datePickerDonePressed:self];
}
}
if ([self.delegate respondsToSelector:@selector(datePicker:selectedDate:)]) {
[self.delegate datePicker:self selectedDate:dateDay.date];
if (!_internalDate || [_internalDate timeIntervalSinceDate:dateDay.date] || _allowSelectionOfSelectedDate) { // new date selected
[self.currentDay setSelected:NO];
[self.currentDay setLightText:![self dateInCurrentMonth:self.currentDay.date]];
[dateDay setSelected:YES];
BOOL dateInDifferentMonth = ![self dateInCurrentMonth:dateDay.date];
NSDate *firstOfCurrentMonth = self.firstOfCurrentMonth;
[self setInternalDate:dateDay.date];
[self setCurrentDay:dateDay];
if (dateInDifferentMonth) {
[self slideTransitionViewInDirection:[dateDay.date timeIntervalSinceDate:firstOfCurrentMonth]<0 ? UISwipeGestureRecognizerDirectionRight : UISwipeGestureRecognizerDirectionLeft];
}
if ([self.delegate respondsToSelector:@selector(datePicker:selectedDate:)]) {
[self.delegate datePicker:self selectedDate:dateDay.date];
}
if (_autoCloseOnSelectDate) {
[self.delegate datePickerDonePressed:self];
}
}
if (_autoCloseOnSelectDate) {
[self.delegate datePickerDonePressed:self];
}
else {
THDateDay* tapDay = dateDay;
if (![_selectedDates containsObject:[self dateWithOutTime:tapDay.date]])
{
[_selectedDates addObject:[self dateWithOutTime:tapDay.date]];
[_selectedDateViews addObject:tapDay];

BOOL dateInDifferentMonth = ![self dateInCurrentMonth:dateDay.date];
[self setInternalDate:dateDay.date];
[self setCurrentDay:dateDay];
if (dateInDifferentMonth) {
[self slideTransitionViewInDirection:[dateDay.date timeIntervalSinceDate:self.firstOfCurrentMonth]>0 ? UISwipeGestureRecognizerDirectionRight : UISwipeGestureRecognizerDirectionLeft];
}
if ([self.delegate respondsToSelector:@selector(datePicker:selectedDate:)]) {
[self.delegate datePicker:self selectedDate:dateDay.date];
}
}
else
{
[tapDay setSelected:NO];
[_selectedDates removeObject:tapDay.date];
[_selectedDateViews removeObject:tapDay];
}

for (THDateDay* selectedDate in _selectedDateViews)
{
[selectedDate setSelected:YES];
}
self.okBtn.enabled = [self shouldOkBeEnabled];
}
}

Expand Down Expand Up @@ -457,7 +585,7 @@ - (void)slideTransitionViewInDirection:(UISwipeGestureRecognizerDirection)dir {
newView.alpha = 0;
[self redraw];
[oldView.superview layoutSubviews];
[UIView animateWithDuration:.5 animations:^{
[UIView animateWithDuration:self.slideAnimationDuration animations:^{
newView.frame = origFrame;
newView.alpha = 1;
oldView.frame = outDestFrame;
Expand Down Expand Up @@ -570,6 +698,14 @@ - (BOOL)dateInCurrentMonth:(NSDate *)date{
return [comp1 year] == [comp2 year] && [comp1 month] == [comp2 month];
}

- (NSDate *)dateWithOutTime:(NSDate *)datDate {
if(!datDate) {
datDate = [NSDate date];
}
NSDateComponents* comps = [[NSCalendar currentCalendar] components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:datDate];
return [[NSCalendar currentCalendar] dateFromComponents:comps];
}

#pragma mark - Cleanup

- (void)didReceiveMemoryWarning {
Expand Down