diff --git a/DSLCalendarView/DSLCalendarDayView.h b/DSLCalendarView/DSLCalendarDayView.h index 54b53d2..e17fa1a 100644 --- a/DSLCalendarView/DSLCalendarDayView.h +++ b/DSLCalendarView/DSLCalendarDayView.h @@ -52,6 +52,7 @@ enum { @property (nonatomic, assign) DSLCalendarDayViewPositionInWeek positionInWeek; @property (nonatomic, assign) DSLCalendarDayViewSelectionState selectionState; @property (nonatomic, assign, getter = isInCurrentMonth) BOOL inCurrentMonth; +@property (nonatomic, assign) BOOL isDisabled; @property (nonatomic, strong, readonly) NSDate *dayAsDate; diff --git a/DSLCalendarView/DSLCalendarDayView.m b/DSLCalendarView/DSLCalendarDayView.m index a6835fd..0fb605d 100644 --- a/DSLCalendarView/DSLCalendarDayView.m +++ b/DSLCalendarView/DSLCalendarDayView.m @@ -175,6 +175,10 @@ - (void)drawDayNumber { [[UIColor whiteColor] set]; } + if (self.isDisabled) { + [[UIColor colorWithWhite:0.702 alpha:1.000] setFill]; + } + UIFont *textFont = [UIFont boldSystemFontOfSize:17.0]; CGSize textSize = [_labelText sizeWithFont:textFont]; diff --git a/DSLCalendarView/DSLCalendarMonthView.h b/DSLCalendarView/DSLCalendarMonthView.h index 72ad381..6afae40 100644 --- a/DSLCalendarView/DSLCalendarMonthView.h +++ b/DSLCalendarView/DSLCalendarMonthView.h @@ -39,6 +39,8 @@ @property (nonatomic, copy, readonly) NSDateComponents *month; @property (nonatomic, strong, readonly) NSSet *dayViews; +@property (nonatomic, strong) NSDate *minimumDate; +@property (nonatomic, strong) NSDate *maximumDate; // Designated initialiser - (id)initWithMonth:(NSDateComponents*)month width:(CGFloat)width dayViewClass:(Class)dayViewClass dayViewHeight:(CGFloat)dayViewHeight; diff --git a/DSLCalendarView/DSLCalendarMonthView.m b/DSLCalendarView/DSLCalendarMonthView.m index 6e69210..75336d4 100644 --- a/DSLCalendarView/DSLCalendarMonthView.m +++ b/DSLCalendarView/DSLCalendarMonthView.m @@ -120,6 +120,12 @@ - (void)createDayViews { break; } + BOOL isDisabled = NO; + if ( (self.minimumDate && [day.date isBeforeDay:self.minimumDate]) || (self.maximumDate && [self.maximumDate isBeforeDay:day.date]) ) { + isDisabled = YES; + } + dayView.isDisabled = isDisabled; + [self.dayViewsDictionary setObject:dayView forKey:[self dayViewKeyForDay:day]]; [self addSubview:dayView]; } @@ -227,4 +233,30 @@ - (DSLCalendarDayView*)dayViewForDay:(NSDateComponents*)day { return [self.dayViewsDictionary objectForKey:[self dayViewKeyForDay:day]]; } +- (void)setMinimumDate:(NSDate *)minimumDate { + _minimumDate = minimumDate; + //redraw dayViews + [self reloadDayViewsMinMaxDate]; +} + +- (void)setMaximumDate:(NSDate *)maximumDate { + _maximumDate = maximumDate; + //redraw dayViews + [self reloadDayViewsMinMaxDate]; +} + +- (void)reloadDayViewsMinMaxDate { + [self.dayViews enumerateObjectsUsingBlock:^(DSLCalendarDayView *dayView, BOOL *stop) { + NSDateComponents *day = dayView.day; + BOOL isDisabled = NO; + if ( (self.minimumDate && [day.date isBeforeDay:self.minimumDate]) || (self.maximumDate && [self.maximumDate isBeforeDay:day.date]) ) { + isDisabled = YES; + } + if (isDisabled != dayView.isDisabled) { + dayView.isDisabled = isDisabled; + [dayView setNeedsDisplay]; + } + }]; +} + @end diff --git a/DSLCalendarView/DSLCalendarRange.h b/DSLCalendarView/DSLCalendarRange.h index a9012ec..4fa48a4 100644 --- a/DSLCalendarView/DSLCalendarRange.h +++ b/DSLCalendarView/DSLCalendarRange.h @@ -42,4 +42,6 @@ - (BOOL)containsDay:(NSDateComponents*)day; - (BOOL)containsDate:(NSDate*)date; +- (BOOL)isEqualToRange:(DSLCalendarRange *)calendarRange; + @end diff --git a/DSLCalendarView/DSLCalendarRange.m b/DSLCalendarView/DSLCalendarRange.m index 5524405..4e139c1 100644 --- a/DSLCalendarView/DSLCalendarRange.m +++ b/DSLCalendarView/DSLCalendarRange.m @@ -98,4 +98,11 @@ - (BOOL)containsDate:(NSDate*)date { return YES; } +- (BOOL)isEqualToRange:(DSLCalendarRange *)calendarRange { + if ([_startDate isEqualToDate:[calendarRange.startDay date]] && [_endDate isEqualToDate:[calendarRange.endDay date]]) { + return YES; + } + return NO; +} + @end diff --git a/DSLCalendarView/DSLCalendarView.h b/DSLCalendarView/DSLCalendarView.h index a1caca5..7e681e1 100644 --- a/DSLCalendarView/DSLCalendarView.h +++ b/DSLCalendarView/DSLCalendarView.h @@ -41,6 +41,8 @@ @property (nonatomic, copy) NSDateComponents *visibleMonth; @property (nonatomic, strong) DSLCalendarRange *selectedRange; @property (nonatomic, assign) BOOL showDayCalloutView; +@property (nonatomic, strong) NSDate *minimumDate; +@property (nonatomic, strong) NSDate *maximumDate; + (Class)monthSelectorViewClass; + (Class)monthViewClass; diff --git a/DSLCalendarView/DSLCalendarView.m b/DSLCalendarView/DSLCalendarView.m index 7666f3a..360b00f 100644 --- a/DSLCalendarView/DSLCalendarView.m +++ b/DSLCalendarView/DSLCalendarView.m @@ -49,6 +49,7 @@ @interface DSLCalendarView () @property (nonatomic, strong) UIView *monthContainerView; @property (nonatomic, strong) UIView *monthContainerViewContentView; @property (nonatomic, strong) DSLCalendarMonthSelectorView *monthSelectorView; +@property (nonatomic, strong) NSDateComponents *lastTouchedDay; @end @@ -165,6 +166,20 @@ - (void)setVisibleMonth:(NSDateComponents *)visibleMonth animated:(BOOL)animated [self positionViewsForMonth:_visibleMonth fromMonth:fromMonth animated:animated]; } +- (void)setMinimumDate:(NSDate *)minimumDate { + _minimumDate = minimumDate; + [self.monthViews enumerateKeysAndObjectsUsingBlock:^(id key, DSLCalendarMonthView *monthView, BOOL *stop) { + monthView.minimumDate = minimumDate; + }]; +} + +- (void)setMaximumDate:(NSDate *)maximumDate { + _maximumDate = maximumDate; + [self.monthViews enumerateKeysAndObjectsUsingBlock:^(id key, DSLCalendarMonthView *monthView, BOOL *stop) { + monthView.maximumDate = maximumDate; + }]; +} + #pragma mark - Events @@ -210,6 +225,8 @@ - (DSLCalendarMonthView*)cachedOrCreatedMonthViewForMonth:(NSDateComponents*)mon [monthView updateDaySelectionStatesForRange:self.selectedRange]; } + monthView.minimumDate = self.minimumDate; + monthView.maximumDate = self.maximumDate; return monthView; } @@ -361,11 +378,19 @@ - (BOOL)monthStartsOnFirstDayOfWeek:(NSDateComponents*)month { - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { DSLCalendarDayView *touchedView = [self dayViewForTouches:touches]; + self.lastTouchedDay = touchedView.day; if (touchedView == nil) { self.draggingStartDay = nil; return; } + if (self.minimumDate && [touchedView.day.date isBeforeDay:self.minimumDate]) { + return; + } + if (self.maximumDate && [self.maximumDate isBeforeDay:touchedView.day.date]) { + return; + } + self.draggingStartDay = touchedView.day; self.draggingFixedDay = touchedView.day; self.draggedOffStartDay = NO; @@ -403,6 +428,19 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { return; } + BOOL isTheSameDay = [self.lastTouchedDay.date isEqualToDate:touchedView.day.date]; + self.lastTouchedDay = touchedView.day; + if (isTheSameDay) { + return; + } + + if (self.minimumDate && [touchedView.day.date isBeforeDay:self.minimumDate]) { + return; + } + if (self.maximumDate && [self.maximumDate isBeforeDay:touchedView.day.date]) { + return; + } + DSLCalendarRange *newRange; if ([touchedView.day.date compare:self.draggingFixedDay.date] == NSOrderedAscending) { newRange = [[DSLCalendarRange alloc] initWithStartDay:touchedView.day endDay:self.draggingFixedDay]; @@ -431,6 +469,7 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { } DSLCalendarDayView *touchedView = [self dayViewForTouches:touches]; + self.lastTouchedDay = touchedView.day; if (touchedView == nil) { self.draggingStartDay = nil; return; @@ -498,7 +537,6 @@ - (DSLCalendarDayView*)dayViewForTouches:(NSSet*)touches { return nil; } - #pragma mark - Day callout view methods - (void)positionCalloutViewForDayView:(DSLCalendarDayView*)dayView { diff --git a/DSLCalendarView/NSDate+DSLCalendarView.h b/DSLCalendarView/NSDate+DSLCalendarView.h index b424ac7..1f962cd 100644 --- a/DSLCalendarView/NSDate+DSLCalendarView.h +++ b/DSLCalendarView/NSDate+DSLCalendarView.h @@ -13,4 +13,10 @@ - (NSDateComponents*)dslCalendarView_dayWithCalendar:(NSCalendar*)calendar; - (NSDateComponents*)dslCalendarView_monthWithCalendar:(NSCalendar*)calendar; + +- (BOOL)isBeforeDay:(NSDate *)day2; +// NSDateAdditions.m +// SymbioCalendar +- (NSDate *)cc_dateByMovingToBeginningOfDay; + @end diff --git a/DSLCalendarView/NSDate+DSLCalendarView.m b/DSLCalendarView/NSDate+DSLCalendarView.m index 89ba68c..8016ecf 100644 --- a/DSLCalendarView/NSDate+DSLCalendarView.m +++ b/DSLCalendarView/NSDate+DSLCalendarView.m @@ -19,4 +19,17 @@ - (NSDateComponents*)dslCalendarView_monthWithCalendar:(NSCalendar*)calendar { return [calendar components:NSCalendarCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit fromDate:self]; } +- (BOOL)isBeforeDay:(NSDate *)day2 { + return ([[self cc_dateByMovingToBeginningOfDay] compare:[day2 cc_dateByMovingToBeginningOfDay]] == NSOrderedAscending); +} + +- (NSDate *)cc_dateByMovingToBeginningOfDay { + unsigned int flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit; + NSDateComponents* parts = [[NSCalendar currentCalendar] components:flags fromDate:self]; + [parts setHour:0]; + [parts setMinute:0]; + [parts setSecond:0]; + return [[NSCalendar currentCalendar] dateFromComponents:parts]; +} + @end diff --git a/Example/DSLCalendarViewExample/ViewController.m b/Example/DSLCalendarViewExample/ViewController.m index d3dba2e..03d871d 100644 --- a/Example/DSLCalendarViewExample/ViewController.m +++ b/Example/DSLCalendarViewExample/ViewController.m @@ -23,6 +23,8 @@ - (void)viewDidLoad // Do any additional setup after loading the view, typically from a nib. self.calendarView.delegate = self; + self.calendarView.minimumDate = [NSDate date]; + self.calendarView.maximumDate = [NSDate dateWithTimeIntervalSinceNow:86400*7]; } - (void)viewDidUnload