diff --git a/Sources/DIDatepicker.h b/Sources/DIDatepicker.h index ba3cf3b..6a77651 100644 --- a/Sources/DIDatepicker.h +++ b/Sources/DIDatepicker.h @@ -5,9 +5,22 @@ #import +// some defines for keys, that should cover the basic configuration for the drawing process +// of DIDatePickerview. It's just colors and fonts for now. For everything else it +// would probably be easier to reimplement the view -extern const NSTimeInterval kSecondsInDay; -extern const CGFloat kDIDetepickerHeight; +#define DIDatePickerViewDayTextColor @"dayTextColor" +#define DIDatePickerViewWeekdayTextColor @"weekdayTextColor" +#define DIDatePickerViewMonthTextColor @"monthTextColor" +#define DIDatePickerViewBackgroundColor @"backgroundColor" + +#define DIDatePickerViewDayTextFont @"dayTextFont" +#define DIDatePickerViewWeekdayTextFont @"weekdayTextFont" +#define DIDatePickerViewWeekendDayTextFont @"weekendDayTextFont" +#define DIDatePickerViewMonthTextFont @"monthTextFont" + +#define DIDatePickerViewLineColor @"lineColor" +#define DIDatePickerViewSelectionColor @"selectionColor" @interface DIDatepicker : UIControl @@ -16,10 +29,20 @@ extern const CGFloat kDIDetepickerHeight; @property (strong, nonatomic) NSArray *dates; @property (strong, nonatomic, readonly) NSDate *selectedDate; -// UI +// UI properties - left in for compability, should they be deprecated? @property (strong, nonatomic) UIColor *bottomLineColor; @property (strong, nonatomic) UIColor *selectedDateBottomLineColor; +// instead of adding a multitude of properties, we use one +// configuration dictionary for the view drawing process +// this allows other view classes to +@property (strong, nonatomic) NSDictionary *viewConfiguration; + +@property (assign) CGFloat spaceBetweenDateViews; + +// configuration of view used. class must conform to +@property (assign) Class viewClass; + // methods - (void)fillDatesFromCurrentDate:(NSInteger)nextDatesCount; - (void)fillDatesFromDate:(NSDate *)fromDate numberOfDays:(NSInteger)nextDatesCount; @@ -28,5 +51,6 @@ extern const CGFloat kDIDetepickerHeight; - (void)fillCurrentYear; - (void)selectDate:(NSDate *)date; - (void)selectDateAtIndex:(NSUInteger)index; +- (void)addViewConfiguration:(NSDictionary *)dictionary; @end diff --git a/Sources/DIDatepicker.m b/Sources/DIDatepicker.m index 84485a9..d52987c 100644 --- a/Sources/DIDatepicker.m +++ b/Sources/DIDatepicker.m @@ -6,11 +6,8 @@ #import "DIDatepicker.h" #import "DIDatepickerDateView.h" - -const NSTimeInterval kSecondsInDay = 86400; +const NSTimeInterval kSecondsInDay = 24 * 60 * 60; const NSInteger kMondayOffset = 2; -const CGFloat kDIDetepickerHeight = 60.; -const CGFloat kDIDatepickerSpaceBetweenItems = 15.; @interface DIDatepicker () @@ -24,6 +21,7 @@ @implementation DIDatepicker - (void)awakeFromNib { + _viewClass = [DIDatepickerDateView class]; [self setupViews]; } @@ -32,6 +30,7 @@ - (id)initWithFrame:(CGRect)frame self = [super initWithFrame:frame]; if (!self) return self; + _viewClass = [DIDatepickerDateView class]; [self setupViews]; return self; @@ -39,10 +38,28 @@ - (id)initWithFrame:(CGRect)frame - (void)setupViews { + self.spaceBetweenDateViews = 15.0; + + _viewConfiguration = @{ + DIDatePickerViewSelectionColor:[UIColor colorWithRed:242./255. green:93./255. blue:28./255. alpha:1.], + DIDatePickerViewLineColor:[UIColor colorWithWhite:0.816 alpha:1.000], + + DIDatePickerViewDayTextFont:[UIFont fontWithName:@"HelveticaNeue-Thin" size:20], + DIDatePickerViewWeekendDayTextFont:[UIFont fontWithName:@"HelveticaNeue-Medium" size:8], + DIDatePickerViewWeekdayTextFont:[UIFont fontWithName:@"HelveticaNeue-Thin" size:8], + DIDatePickerViewMonthTextFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:8], + + DIDatePickerViewMonthTextColor:[UIColor colorWithRed:153./255. green:153./255. blue:153./255. alpha:1.], + DIDatePickerViewWeekdayTextColor:[UIColor blackColor], + DIDatePickerViewDayTextColor:[UIColor blackColor], + }; + self.autoresizingMask = UIViewAutoresizingFlexibleWidth; self.backgroundColor = [UIColor whiteColor]; - self.bottomLineColor = [UIColor colorWithWhite:0.816 alpha:1.000]; - self.selectedDateBottomLineColor = [UIColor colorWithRed:0.910 green:0.278 blue:0.128 alpha:1.000]; + self.bottomLineColor = nil; + + //now default is to use dictionary above, + self.selectedDateBottomLineColor = nil; } @@ -57,13 +74,22 @@ - (void)setDates:(NSArray *)dates self.selectedDate = nil; } +// custom accessor merges a partial dictionary with the one already available (e.g. the default one set in setupView) +// this way users can keep defaults where needed +- (void)addViewConfiguration:(NSDictionary *)newConfiguration +{ + NSMutableDictionary *tmp = [_viewConfiguration mutableCopy]; + [tmp addEntriesFromDictionary:newConfiguration]; + _viewConfiguration = [tmp copy]; +} + - (void)setSelectedDate:(NSDate *)selectedDate { _selectedDate = selectedDate; for (id subview in self.datesScrollView.subviews) { - if ([subview isKindOfClass:[DIDatepickerDateView class]]) { - DIDatepickerDateView *dateView = (DIDatepickerDateView *)subview; + if ([subview isKindOfClass:[_viewClass class]]) { + UIControl *dateView = (UIControl *)subview; dateView.isSelected = [dateView.date isEqualToDate:selectedDate]; } } @@ -89,8 +115,8 @@ - (void)setSelectedDateBottomLineColor:(UIColor *)selectedDateBottomLineColor _selectedDateBottomLineColor = selectedDateBottomLineColor; for (id subview in self.datesScrollView.subviews) { - if ([subview isKindOfClass:[DIDatepickerDateView class]]) { - DIDatepickerDateView *dateView = (DIDatepickerDateView *)subview; + if ([subview conformsToProtocol:@protocol(DIDatepickerViewProtocol)]) { + UIControl *dateView = (UIControl *)subview; [dateView setItemSelectionColor:selectedDateBottomLineColor]; } } @@ -132,7 +158,7 @@ - (void)fillCurrentWeek NSMutableArray *dates = [[NSMutableArray alloc] init]; for (NSInteger weekday = 0; weekday < 7; weekday++) { - [dates addObject:[NSDate dateWithTimeInterval:(kMondayOffset + weekday - todayComponents.weekday)*kSecondsInDay sinceDate:today]]; + [dates addObject:[NSDate dateWithTimeInterval:(kMondayOffset + weekday - todayComponents.weekday) * kSecondsInDay sinceDate:today]]; } self.dates = dates; @@ -213,7 +239,14 @@ - (void)drawRect:(CGRect)rect // draw bottom line CGContextRef context = UIGraphicsGetCurrentContext(); - CGContextSetStrokeColorWithColor(context, self.bottomLineColor.CGColor); + if (self.bottomLineColor) { + CGContextSetStrokeColorWithColor(context, self.bottomLineColor.CGColor); + } + else { + UIColor *lineColor = [_viewConfiguration objectForKey:DIDatePickerViewLineColor]; + CGContextSetStrokeColorWithColor(context, lineColor.CGColor); + } + CGContextSetLineWidth(context, .5); CGContextMoveToPoint(context, 0, rect.size.height - .5); CGContextAddLineToPoint(context, rect.size.width, rect.size.height - .5); @@ -224,23 +257,29 @@ - (void)updateDatesView { [self.datesScrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; - CGFloat currentItemXPosition = kDIDatepickerSpaceBetweenItems; + CGFloat currentItemXPosition = self.spaceBetweenDateViews; for (NSDate *date in self.dates) { - DIDatepickerDateView *dateView = [[DIDatepickerDateView alloc] initWithFrame:CGRectMake(currentItemXPosition, 0, kDIDatepickerItemWidth, self.frame.size.height)]; + UIControl *dateView = [[_viewClass alloc] initWithFrame:CGRectMake(currentItemXPosition, + 0, + [_viewClass itemWidth], + self.frame.size.height)]; + dateView.viewConfiguration = _viewConfiguration; dateView.date = date; dateView.selected = [date isEqualToDate:self.selectedDate]; - [dateView setItemSelectionColor:self.selectedDateBottomLineColor]; + if (self.selectedDateBottomLineColor) { + [dateView setItemSelectionColor:self.selectedDateBottomLineColor]; + } [dateView addTarget:self action:@selector(updateSelectedDate:) forControlEvents:UIControlEventValueChanged]; [self.datesScrollView addSubview:dateView]; - currentItemXPosition += kDIDatepickerItemWidth + kDIDatepickerSpaceBetweenItems; + currentItemXPosition += [_viewClass itemWidth] + self.spaceBetweenDateViews; } self.datesScrollView.contentSize = CGSizeMake(currentItemXPosition, self.frame.size.height); } -- (void)updateSelectedDate:(DIDatepickerDateView *)dateView +- (void)updateSelectedDate:(UIControl *)dateView { self.selectedDate = dateView.date; } @@ -249,8 +288,8 @@ - (void)updateSelectedDatePosition { NSUInteger itemIndex = [self.dates indexOfObject:self.selectedDate]; - CGSize itemSize = CGSizeMake(kDIDatepickerItemWidth + kDIDatepickerSpaceBetweenItems, self.frame.size.height); - CGFloat itemOffset = itemSize.width * itemIndex - (self.frame.size.width - (kDIDatepickerItemWidth + 2 * kDIDatepickerSpaceBetweenItems)) / 2; + CGSize itemSize = CGSizeMake([_viewClass itemWidth] + self.spaceBetweenDateViews, self.frame.size.height); + CGFloat itemOffset = itemSize.width * itemIndex - (self.frame.size.width - ([_viewClass itemWidth] + 2 * self.spaceBetweenDateViews)) / 2; itemOffset = MAX(0, MIN(self.datesScrollView.contentSize.width - (self.frame.size.width ), itemOffset)); diff --git a/Sources/DIDatepickerDateView.h b/Sources/DIDatepickerDateView.h index 08d7ffe..c7c8bfb 100644 --- a/Sources/DIDatepickerDateView.h +++ b/Sources/DIDatepickerDateView.h @@ -5,18 +5,28 @@ #import +@protocol DIDatepickerViewProtocol -extern const CGFloat kDIDatepickerItemWidth; -extern const CGFloat kDIDatepickerSelectionLineWidth; - - -@interface DIDatepickerDateView : UIControl +@required // data @property (strong, nonatomic) NSDate *date; @property (assign, nonatomic) BOOL isSelected; +@property (strong, nonatomic) NSDictionary *viewConfiguration; + +// class methods communicating the size requirements of the view implementation ++ (CGFloat)itemWidth; -// methods + +// deprecated methods, superseeded by viewConfiguration - (void)setItemSelectionColor:(UIColor *)itemSelectionColor; @end + +@interface DIDatepickerDateView : UIControl + +@property (strong, nonatomic) NSDictionary *viewConfiguration; +@property (strong, nonatomic) NSDate *date; +@property (assign, nonatomic) BOOL isSelected; + +@end diff --git a/Sources/DIDatepickerDateView.m b/Sources/DIDatepickerDateView.m index 05a13c7..3b7a3a8 100644 --- a/Sources/DIDatepickerDateView.m +++ b/Sources/DIDatepickerDateView.m @@ -4,11 +4,7 @@ // #import "DIDatepickerDateView.h" - - -const CGFloat kDIDatepickerItemWidth = 46.; -const CGFloat kDIDatepickerSelectionLineWidth = 51.; - +#import "DIDatepicker.h" @interface DIDatepickerDateView () @@ -20,6 +16,11 @@ @interface DIDatepickerDateView () @implementation DIDatepickerDateView ++ (CGFloat)itemWidth +{ + return 46.0; +} + - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -53,26 +54,26 @@ - (void)setDate:(NSDate *)date NSMutableAttributedString *dateString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@\n%@", dayFormattedString, [dayInWeekFormattedString uppercaseString], monthFormattedString]]; [dateString addAttributes:@{ - NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Thin" size:20], - NSForegroundColorAttributeName: [UIColor blackColor] + NSFontAttributeName: [_viewConfiguration objectForKey:DIDatePickerViewDayTextFont], + NSForegroundColorAttributeName: [_viewConfiguration objectForKey:DIDatePickerViewDayTextColor] } range:NSMakeRange(0, dayFormattedString.length)]; [dateString addAttributes:@{ - NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Thin" size:8], - NSForegroundColorAttributeName: [UIColor blackColor] + NSFontAttributeName: [_viewConfiguration objectForKey:DIDatePickerViewWeekdayTextFont], + NSForegroundColorAttributeName:[_viewConfiguration objectForKey:DIDatePickerViewWeekdayTextColor], } range:NSMakeRange(dayFormattedString.length + 1, dayInWeekFormattedString.length)]; [dateString addAttributes:@{ - NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue-Light" size:8], - NSForegroundColorAttributeName: [UIColor colorWithRed:153./255. green:153./255. blue:153./255. alpha:1.] + NSFontAttributeName: [_viewConfiguration objectForKey:DIDatePickerViewMonthTextFont], + NSForegroundColorAttributeName:[_viewConfiguration objectForKey:DIDatePickerViewMonthTextColor] } range:NSMakeRange(dateString.string.length - monthFormattedString.length, monthFormattedString.length)]; if ([self isWeekday:date]) { [dateString addAttribute:NSFontAttributeName - value:[UIFont fontWithName:@"HelveticaNeue-Medium" size:8] + value:[_viewConfiguration objectForKey:DIDatePickerViewWeekendDayTextFont] range:NSMakeRange(dayFormattedString.length + 1, dayInWeekFormattedString.length)]; } @@ -103,7 +104,7 @@ - (UIView *)selectionView if (!_selectionView) { _selectionView = [[UIView alloc] initWithFrame:CGRectMake((self.frame.size.width - 51) / 2, self.frame.size.height - 3, 51, 3)]; _selectionView.alpha = 0; - _selectionView.backgroundColor = [UIColor colorWithRed:242./255. green:93./255. blue:28./255. alpha:1.]; + _selectionView.backgroundColor = [self.viewConfiguration objectForKey:DIDatePickerViewSelectionColor]; [self addSubview:_selectionView]; }