diff --git a/Examples/Calendar.xcodeproj/project.pbxproj b/Examples/Calendar.xcodeproj/project.pbxproj index 40aab67..cb30bbd 100644 --- a/Examples/Calendar.xcodeproj/project.pbxproj +++ b/Examples/Calendar.xcodeproj/project.pbxproj @@ -16,10 +16,6 @@ 1D2391395A8710F3E85A74 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D2391395A8710F3E85A73 /* QuartzCore.framework */; }; 1D2391395A8710F3E85A76 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D2391395A8710F3E85A75 /* CoreGraphics.framework */; }; 1D2391395A8710F3E85A85 /* CKCalendarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D2391395A8710F3E85A84 /* CKCalendarView.m */; }; - 1D2391395A8710F3E85A88 /* left_arrow.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D2391395A8710F3E85A87 /* left_arrow.png */; }; - 1D2391395A8710F3E85A8A /* left_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D2391395A8710F3E85A89 /* left_arrow@2x.png */; }; - 1D2391395A8710F3E85A8C /* right_arrow.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D2391395A8710F3E85A8B /* right_arrow.png */; }; - 1D2391395A8710F3E85A8E /* right_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1D2391395A8710F3E85A8D /* right_arrow@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -38,10 +34,6 @@ 1D2391395A8710F3E85A75 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 1D2391395A8710F3E85A83 /* CKCalendarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CKCalendarView.h; path = ../../Source/CKCalendarView.h; sourceTree = ""; }; 1D2391395A8710F3E85A84 /* CKCalendarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CKCalendarView.m; path = ../../Source/CKCalendarView.m; sourceTree = ""; }; - 1D2391395A8710F3E85A87 /* left_arrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = left_arrow.png; path = ../../Source/resources/left_arrow.png; sourceTree = ""; }; - 1D2391395A8710F3E85A89 /* left_arrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "left_arrow@2x.png"; path = "../../Source/resources/left_arrow@2x.png"; sourceTree = ""; }; - 1D2391395A8710F3E85A8B /* right_arrow.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = right_arrow.png; path = ../../Source/resources/right_arrow.png; sourceTree = ""; }; - 1D2391395A8710F3E85A8D /* right_arrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "right_arrow@2x.png"; path = "../../Source/resources/right_arrow@2x.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -90,10 +82,10 @@ 1D2391395A8710F3E85A5A /* Calendar */ = { isa = PBXGroup; children = ( - 1D2391395A8710F3E85A84 /* CKCalendarView.m */, 1D2391395A8710F3E85A83 /* CKCalendarView.h */, - 1D2391395A8710F3E85A67 /* CKViewController.m */, + 1D2391395A8710F3E85A84 /* CKCalendarView.m */, 1D2391395A8710F3E85A66 /* CKViewController.h */, + 1D2391395A8710F3E85A67 /* CKViewController.m */, 1D2391395A8710F3E85A64 /* CKAppDelegate.m */, 1D2391395A8710F3E85A63 /* CKAppDelegate.h */, 1D2391395A8710F3E85A5B /* Supporting Files */, @@ -116,10 +108,6 @@ 1D2391395A8710F3E85A86 /* resources */ = { isa = PBXGroup; children = ( - 1D2391395A8710F3E85A8D /* right_arrow@2x.png */, - 1D2391395A8710F3E85A8B /* right_arrow.png */, - 1D2391395A8710F3E85A89 /* left_arrow@2x.png */, - 1D2391395A8710F3E85A87 /* left_arrow.png */, ); name = resources; sourceTree = ""; @@ -149,6 +137,9 @@ /* Begin PBXProject section */ 001D2391395A8710F3E85A45 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0460; + }; buildConfigurationList = 1D2391395A8710F3E85A46 /* Build configuration list for PBXProject "Calendar" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; @@ -172,10 +163,6 @@ buildActionMask = 2147483647; files = ( 1D2391395A8710F3E85A5F /* InfoPlist.strings in Resources */, - 1D2391395A8710F3E85A88 /* left_arrow.png in Resources */, - 1D2391395A8710F3E85A8A /* left_arrow@2x.png in Resources */, - 1D2391395A8710F3E85A8C /* right_arrow.png in Resources */, - 1D2391395A8710F3E85A8E /* right_arrow@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -213,6 +200,10 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -234,6 +225,10 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -295,6 +290,7 @@ 1D2391395A8710F3E85A4F /* Debug */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/Examples/Calendar/CKViewController.m b/Examples/Calendar/CKViewController.m index b22b816..dd3a4f2 100644 --- a/Examples/Calendar/CKViewController.m +++ b/Examples/Calendar/CKViewController.m @@ -9,6 +9,7 @@ @interface CKViewController () @property(nonatomic, strong) NSDateFormatter *dateFormatter; @property(nonatomic, strong) NSDate *minimumDate; @property(nonatomic, strong) NSArray *disabledDates; +@property(nonatomic, strong) NSArray *birthDays; @end @@ -17,7 +18,7 @@ @implementation CKViewController - (id)init { self = [super init]; if (self) { - CKCalendarView *calendar = [[CKCalendarView alloc] initWithStartDay:startMonday]; + CKCalendarView *calendar = [[CKCalendarView alloc] initWithStartDay:SATURDAY]; self.calendar = calendar; calendar.delegate = self; @@ -30,11 +31,23 @@ - (id)init { [self.dateFormatter dateFromString:@"06/01/2013"], [self.dateFormatter dateFromString:@"07/01/2013"] ]; + + self.birthDays = @[ + [self.dateFormatter dateFromString:@"07/01/2013"], + [self.dateFormatter dateFromString:@"11/01/2013"], + [self.dateFormatter dateFromString:@"05/02/2013"], + [self.dateFormatter dateFromString:@"25/01/2013"] + ]; + + self.calendar.offDays = @[ + [NSNumber numberWithInt:FRIDAY], + [NSNumber numberWithInt:SATURDAY] + ]; calendar.onlyShowCurrentMonth = NO; calendar.adaptHeightToNumberOfWeeksInMonth = YES; - calendar.frame = CGRectMake(10, 10, 300, 320); + calendar.frame = CGRectMake(10, 50, 300, 320); [self.view addSubview:calendar]; self.dateLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, CGRectGetMaxY(calendar.frame) + 4, self.view.bounds.size.width, 24)]; @@ -77,12 +90,7 @@ - (void)localeDidChange { } - (BOOL)dateIsDisabled:(NSDate *)date { - for (NSDate *disabledDate in self.disabledDates) { - if ([disabledDate isEqualToDate:date]) { - return YES; - } - } - return NO; + return [self.disabledDates containsObject:date]; } #pragma mark - @@ -93,6 +101,13 @@ - (void)calendar:(CKCalendarView *)calendar configureDateItem:(CKDateItem *)date if ([self dateIsDisabled:date]) { dateItem.backgroundColor = [UIColor redColor]; dateItem.textColor = [UIColor whiteColor]; + dateItem.offDayTextColor = [UIColor whiteColor]; + } + if ([self.birthDays containsObject:date]) { + if([self dateIsDisabled:date]) + dateItem.notificationColor = [UIColor cyanColor]; + else + dateItem.notificationColor = [UIColor purpleColor]; } } diff --git a/Source/CKCalendarView.h b/Source/CKCalendarView.h index 11f4837..0c274e6 100644 --- a/Source/CKCalendarView.h +++ b/Source/CKCalendarView.h @@ -23,23 +23,31 @@ @property (nonatomic, strong) UIColor *selectedBackgroundColor; @property (nonatomic, strong) UIColor *textColor; @property (nonatomic, strong) UIColor *selectedTextColor; +@property (nonatomic, strong) UIColor *offDayTextColor; +@property (nonatomic, strong) UIColor *notificationColor; // default: nil for no notification @end typedef enum { - startSunday = 1, - startMonday = 2, -} CKCalendarStartDay; + SUNDAY = 1, + MONDAY = 2, + TUESDAY = 3, + WEDNESDAY = 4, + THURSDAY = 5, + FRIDAY = 6, + SATURDAY = 7 +} CKCalendarWeekDay; @interface CKCalendarView : UIView -- (id)initWithStartDay:(CKCalendarStartDay)firstDay; -- (id)initWithStartDay:(CKCalendarStartDay)firstDay frame:(CGRect)frame; +- (id)initWithStartDay:(CKCalendarWeekDay)firstDay; +- (id)initWithStartDay:(CKCalendarWeekDay)firstDay frame:(CGRect)frame; -@property (nonatomic) CKCalendarStartDay calendarStartDay; +@property (nonatomic) CKCalendarWeekDay calendarStartDay; @property (nonatomic, strong) NSLocale *locale; @property (nonatomic) BOOL onlyShowCurrentMonth; @property (nonatomic) BOOL adaptHeightToNumberOfWeeksInMonth; +@property (nonatomic, strong) NSArray *offDays; @property (nonatomic, weak) id delegate; @@ -49,6 +57,7 @@ typedef enum { @property (nonatomic, strong) UIFont *dateOfWeekFont; @property (nonatomic, strong) UIColor *dayOfWeekTextColor; @property (nonatomic, strong) UIFont *dateFont; +@property (nonatomic) CGSize monthButtonSize; - (void)setMonthButtonColor:(UIColor *)color; - (void)setInnerBorderColor:(UIColor *)color; diff --git a/Source/CKCalendarView.m b/Source/CKCalendarView.m index 0ae2e98..9578985 100644 --- a/Source/CKCalendarView.m +++ b/Source/CKCalendarView.m @@ -27,8 +27,17 @@ #define DEFAULT_CELL_WIDTH 43 #define CELL_BORDER_WIDTH 1 +#define DEFAULT_MONTH_BUTTON_SIZE CGSizeMake(14,17) + #define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0] +#define kNotificationTag 321 + +typedef enum { + ARROW_LEFT, + ARROW_RIGHT, + ARROW_NOTIFICATION +} ARROW_STYLE; @class CALayer; @class CAGradientLayer; @@ -92,6 +101,8 @@ - (id)init { self.selectedBackgroundColor = UIColorFromRGB(0x88B6DB); self.textColor = UIColorFromRGB(0x393B40); self.selectedTextColor = UIColorFromRGB(0xF2F2F2); + self.offDayTextColor = UIColorFromRGB(0xFF0000); + self.notificationColor = nil; } return self; } @@ -101,7 +112,7 @@ - (id)init { @interface CKCalendarView () @property(nonatomic, strong) UIView *highlight; -@property(nonatomic, strong) UILabel *titleLabel; +@property(nonatomic, strong) UIButton *titleButton; @property(nonatomic, strong) UIButton *prevButton; @property(nonatomic, strong) UIButton *nextButton; @property(nonatomic, strong) UIView *calendarContainer; @@ -120,7 +131,7 @@ @interface CKCalendarView () @implementation CKCalendarView @synthesize highlight = _highlight; -@synthesize titleLabel = _titleLabel; +@synthesize titleButton = _titleButton; @synthesize prevButton = _prevButton; @synthesize nextButton = _nextButton; @synthesize calendarContainer = _calendarContainer; @@ -140,60 +151,66 @@ @implementation CKCalendarView @synthesize onlyShowCurrentMonth = _onlyShowCurrentMonth; @synthesize adaptHeightToNumberOfWeeksInMonth = _adaptHeightToNumberOfWeeksInMonth; +@synthesize monthButtonSize = _monthButtonSize; +@synthesize offDays = _offDays; + @dynamic locale; - (id)init { - return [self initWithStartDay:startSunday]; + return [self initWithStartDay:SUNDAY]; } -- (id)initWithStartDay:(CKCalendarStartDay)firstDay { +- (id)initWithStartDay:(CKCalendarWeekDay)firstDay { return [self initWithStartDay:firstDay frame:CGRectMake(0, 0, 320, 320)]; } -- (void)_init:(CKCalendarStartDay)firstDay { +- (void)_init:(CKCalendarWeekDay)firstDay { self.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; [self.calendar setLocale:[NSLocale currentLocale]]; - + self.cellWidth = DEFAULT_CELL_WIDTH; - + self.dateFormatter = [[NSDateFormatter alloc] init]; [self.dateFormatter setTimeStyle:NSDateFormatterNoStyle]; self.dateFormatter.dateFormat = @"LLLL yyyy"; - + self.calendarStartDay = firstDay; self.onlyShowCurrentMonth = YES; self.adaptHeightToNumberOfWeeksInMonth = YES; - + + self.monthButtonSize = DEFAULT_MONTH_BUTTON_SIZE; + self.offDays = @[[NSNumber numberWithInt:SUNDAY]]; + self.layer.cornerRadius = 6.0f; - + UIView *highlight = [[UIView alloc] initWithFrame:CGRectZero]; highlight.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.2]; highlight.layer.cornerRadius = 6.0f; [self addSubview:highlight]; self.highlight = highlight; - + // SET UP THE HEADER - UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; - titleLabel.textAlignment = NSTextAlignmentCenter; - titleLabel.backgroundColor = [UIColor clearColor]; - titleLabel.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth; - [self addSubview:titleLabel]; - self.titleLabel = titleLabel; - + UIButton *titleButton = [UIButton buttonWithType:UIButtonTypeCustom]; + titleButton.titleLabel.textAlignment = NSTextAlignmentCenter; + titleButton.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth; + [titleButton addTarget:self action:@selector(_moveCalendarToToday) forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:titleButton]; + self.titleButton = titleButton; + UIButton *prevButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [prevButton setImage:[UIImage imageNamed:@"left_arrow.png"] forState:UIControlStateNormal]; + [prevButton setImage:[CKCalendarView _arrowWithColor:[UIColor whiteColor] size:self.monthButtonSize style:ARROW_LEFT] forState:UIControlStateNormal]; prevButton.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin; [prevButton addTarget:self action:@selector(_moveCalendarToPreviousMonth) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:prevButton]; self.prevButton = prevButton; - + UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [nextButton setImage:[UIImage imageNamed:@"right_arrow.png"] forState:UIControlStateNormal]; + [nextButton setImage:[CKCalendarView _arrowWithColor:[UIColor whiteColor] size:self.monthButtonSize style:ARROW_RIGHT] forState:UIControlStateNormal]; nextButton.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin; [nextButton addTarget:self action:@selector(_moveCalendarToNextMonth) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:nextButton]; self.nextButton = nextButton; - + // THE CALENDAR ITSELF UIView *calendarContainer = [[UIView alloc] initWithFrame:CGRectZero]; calendarContainer.layer.borderWidth = 1.0f; @@ -203,12 +220,12 @@ - (void)_init:(CKCalendarStartDay)firstDay { calendarContainer.clipsToBounds = YES; [self addSubview:calendarContainer]; self.calendarContainer = calendarContainer; - + GradientView *daysHeader = [[GradientView alloc] initWithFrame:CGRectZero]; daysHeader.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth; [self.calendarContainer addSubview:daysHeader]; self.daysHeader = daysHeader; - + NSMutableArray *labels = [NSMutableArray array]; for (int i = 0; i < 7; ++i) { UILabel *dayOfWeekLabel = [[UILabel alloc] initWithFrame:CGRectZero]; @@ -221,7 +238,7 @@ - (void)_init:(CKCalendarStartDay)firstDay { } self.dayOfWeekLabels = labels; [self _updateDayOfWeekLabels]; - + // at most we'll need 42 buttons, so let's just bite the bullet and make them now... NSMutableArray *dateButtons = [NSMutableArray array]; for (NSInteger i = 1; i <= 42; i++) { @@ -231,7 +248,7 @@ - (void)_init:(CKCalendarStartDay)firstDay { [dateButtons addObject:dateButton]; } self.dateButtons = dateButtons; - + // initialize the thing self.monthShowing = [NSDate date]; [self _setDefaultStyle]; @@ -239,7 +256,7 @@ - (void)_init:(CKCalendarStartDay)firstDay { [self layoutSubviews]; // TODO: this is a hack to get the first month to show properly } -- (id)initWithStartDay:(CKCalendarStartDay)firstDay frame:(CGRect)frame { +- (id)initWithStartDay:(CKCalendarWeekDay)firstDay frame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self _init:firstDay]; @@ -248,71 +265,75 @@ - (id)initWithStartDay:(CKCalendarStartDay)firstDay frame:(CGRect)frame { } - (id)initWithFrame:(CGRect)frame { - return [self initWithStartDay:startSunday frame:frame]; + return [self initWithStartDay:SUNDAY frame:frame]; } - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { - [self _init:startSunday]; + [self _init:SUNDAY]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; - + CGFloat containerWidth = self.bounds.size.width - (CALENDAR_MARGIN * 2); - self.cellWidth = (floorf(containerWidth / 7.0)) - CELL_BORDER_WIDTH; - + self.cellWidth = (floorf((containerWidth-CELL_BORDER_WIDTH) / 7.0)) - CELL_BORDER_WIDTH; + + // distribute floored diff to both side + CGFloat cellXOffset = ((containerWidth-CELL_BORDER_WIDTH) - (self.cellWidth+CELL_BORDER_WIDTH)*7)/2; + NSInteger numberOfWeeksToShow = 6; if (self.adaptHeightToNumberOfWeeksInMonth) { numberOfWeeksToShow = [self _numberOfWeeksInMonthContainingDate:self.monthShowing]; } - CGFloat containerHeight = (numberOfWeeksToShow * (self.cellWidth + CELL_BORDER_WIDTH) + DAYS_HEADER_HEIGHT); - + CGFloat containerHeight = (numberOfWeeksToShow * (self.cellWidth + CELL_BORDER_WIDTH) + DAYS_HEADER_HEIGHT + CELL_BORDER_WIDTH); + CGRect newFrame = self.frame; newFrame.size.height = containerHeight + CALENDAR_MARGIN + TOP_HEIGHT; self.frame = newFrame; - + self.highlight.frame = CGRectMake(1, 1, self.bounds.size.width - 2, 1); - - self.titleLabel.text = [self.dateFormatter stringFromDate:_monthShowing]; - self.titleLabel.frame = CGRectMake(0, 0, self.bounds.size.width, TOP_HEIGHT); + + [self setTitleButtonText:[self.dateFormatter stringFromDate:_monthShowing]]; + self.titleButton.frame = CGRectMake(0, 0, self.bounds.size.width, TOP_HEIGHT); + self.titleButton.titleLabel.frame = CGRectMake(0, 0, self.titleButton.frame.size.width, self.titleButton.frame.size.height); self.prevButton.frame = CGRectMake(BUTTON_MARGIN, BUTTON_MARGIN, 48, 38); self.nextButton.frame = CGRectMake(self.bounds.size.width - 48 - BUTTON_MARGIN, BUTTON_MARGIN, 48, 38); - - self.calendarContainer.frame = CGRectMake(CALENDAR_MARGIN, CGRectGetMaxY(self.titleLabel.frame), containerWidth, containerHeight); + + self.calendarContainer.frame = CGRectMake(CALENDAR_MARGIN, CGRectGetMaxY(self.titleButton.frame), containerWidth, containerHeight); self.daysHeader.frame = CGRectMake(0, 0, self.calendarContainer.frame.size.width, DAYS_HEADER_HEIGHT); - + CGRect lastDayFrame = CGRectZero; for (UILabel *dayLabel in self.dayOfWeekLabels) { dayLabel.frame = CGRectMake(CGRectGetMaxX(lastDayFrame) + CELL_BORDER_WIDTH, lastDayFrame.origin.y, self.cellWidth, self.daysHeader.frame.size.height); lastDayFrame = dayLabel.frame; } - + for (DateButton *dateButton in self.dateButtons) { [dateButton removeFromSuperview]; } - + NSDate *date = [self _firstDayOfMonthContainingDate:self.monthShowing]; if (!self.onlyShowCurrentMonth) { while ([self _placeInWeekForDate:date] != 0) { date = [self _previousDay:date]; } } - + NSDate *endDate = [self _firstDayOfNextMonthContainingDate:self.monthShowing]; if (!self.onlyShowCurrentMonth) { NSDateComponents *comps = [[NSDateComponents alloc] init]; [comps setWeek:numberOfWeeksToShow]; endDate = [self.calendar dateByAddingComponents:comps toDate:date options:0]; } - + NSUInteger dateButtonPosition = 0; while ([date laterDate:endDate] != date) { DateButton *dateButton = [self.dateButtons objectAtIndex:dateButtonPosition]; - + dateButton.date = date; CKDateItem *item = [[CKDateItem alloc] init]; if ([self _dateIsToday:dateButton.date]) { @@ -320,24 +341,51 @@ - (void)layoutSubviews { item.backgroundColor = [UIColor lightGrayColor]; } else if (!self.onlyShowCurrentMonth && [self _compareByMonth:date toDate:self.monthShowing] != NSOrderedSame) { item.textColor = [UIColor lightGrayColor]; + item.offDayTextColor = UIColorFromRGB(0xFFCCCC); } - + + // Override style with user-style if (self.delegate && [self.delegate respondsToSelector:@selector(calendar:configureDateItem:forDate:)]) { [self.delegate calendar:self configureDateItem:item forDate:date]; } - + + // Selected Day if (self.selectedDate && [self date:self.selectedDate isSameDayAsDate:date]) { [dateButton setTitleColor:item.selectedTextColor forState:UIControlStateNormal]; dateButton.backgroundColor = item.selectedBackgroundColor; - } else { + } + // Off Day + else if ([self _dateIsOffday:date]) { + [dateButton setTitleColor:item.offDayTextColor forState:UIControlStateNormal]; + dateButton.backgroundColor = item.backgroundColor; + } + // Normal Day + else { [dateButton setTitleColor:item.textColor forState:UIControlStateNormal]; dateButton.backgroundColor = item.backgroundColor; } - - dateButton.frame = [self _calculateDayCellFrame:date]; - + + dateButton.frame = [self _calculateDateCellFrame:date offsetX:cellXOffset]; + + if (item.notificationColor) { + UIImage *img = [CKCalendarView _arrowWithColor:item.notificationColor + size:CGSizeMake(10, 10) + style:ARROW_NOTIFICATION]; + UIImageView *imgView = (UIImageView *)[dateButton viewWithTag:kNotificationTag]; + if (!imgView) { + imgView = [[UIImageView alloc] initWithImage:img]; + imgView.tag = kNotificationTag; + imgView.frame = CGRectMake(2, 2, imgView.frame.size.width, imgView.frame.size.height); + [dateButton addSubview:imgView]; + } else + [imgView setImage:img]; + } else if ([dateButton viewWithTag:kNotificationTag]){ + UIView *imgView = [dateButton viewWithTag:kNotificationTag]; + [imgView removeFromSuperview]; + } + [self.calendarContainer addSubview:dateButton]; - + date = [self _nextDay:date]; dateButtonPosition++; } @@ -351,7 +399,7 @@ - (void)_updateDayOfWeekLabels { weekdays = [[weekdays subarrayWithRange:NSMakeRange(firstWeekdayIndex, 7 - firstWeekdayIndex)] arrayByAddingObjectsFromArray:[weekdays subarrayWithRange:NSMakeRange(0, firstWeekdayIndex)]]; } - + NSUInteger i = 0; for (NSString *day in weekdays) { [[self.dayOfWeekLabels objectAtIndex:i] setText:[day uppercaseString]]; @@ -359,7 +407,7 @@ - (void)_updateDayOfWeekLabels { } } -- (void)setCalendarStartDay:(CKCalendarStartDay)calendarStartDay { +- (void)setCalendarStartDay:(CKCalendarWeekDay)calendarStartDay { _calendarStartDay = calendarStartDay; [self.calendar setFirstWeekday:self.calendarStartDay]; [self _updateDayOfWeekLabels]; @@ -418,31 +466,28 @@ - (void)reloadDates:(NSArray *)dates { - (void)_setDefaultStyle { self.backgroundColor = UIColorFromRGB(0x393B40); - + [self setTitleColor:[UIColor whiteColor]]; [self setTitleFont:[UIFont boldSystemFontOfSize:17.0]]; - + [self setDayOfWeekFont:[UIFont boldSystemFontOfSize:12.0]]; [self setDayOfWeekTextColor:UIColorFromRGB(0x999999)]; [self setDayOfWeekBottomColor:UIColorFromRGB(0xCCCFD5) topColor:[UIColor whiteColor]]; - + [self setDateFont:[UIFont boldSystemFontOfSize:16.0f]]; [self setDateBorderColor:UIColorFromRGB(0xDAE1E6)]; } -- (CGRect)_calculateDayCellFrame:(NSDate *)date { +- (CGRect)_calculateDateCellFrame:(NSDate *)date offsetX: (CGFloat) offsetX { NSInteger numberOfDaysSinceBeginningOfThisMonth = [self _numberOfDaysFromDate:self.monthShowing toDate:date]; NSInteger row = (numberOfDaysSinceBeginningOfThisMonth + [self _placeInWeekForDate:self.monthShowing]) / 7; NSInteger placeInWeek = [self _placeInWeekForDate:date]; - - return CGRectMake(placeInWeek * (self.cellWidth + CELL_BORDER_WIDTH), (row * (self.cellWidth + CELL_BORDER_WIDTH)) + CGRectGetMaxY(self.daysHeader.frame) + CELL_BORDER_WIDTH, self.cellWidth, self.cellWidth); + + return CGRectMake(placeInWeek * (self.cellWidth + CELL_BORDER_WIDTH) + CELL_BORDER_WIDTH + offsetX, (row * (self.cellWidth + CELL_BORDER_WIDTH)) + CGRectGetMaxY(self.daysHeader.frame) + CELL_BORDER_WIDTH, self.cellWidth, self.cellWidth); } -- (void)_moveCalendarToNextMonth { - NSDateComponents* comps = [[NSDateComponents alloc] init]; - [comps setMonth:1]; - NSDate *newMonth = [self.calendar dateByAddingComponents:comps toDate:self.monthShowing options:0]; +- (void)_moveCalendarToMonth:(NSDate *)newMonth { if ([self.delegate respondsToSelector:@selector(calendar:willChangeToMonth:)] && ![self.delegate calendar:self willChangeToMonth:newMonth]) { return; } else { @@ -453,18 +498,22 @@ - (void)_moveCalendarToNextMonth { } } +- (void)_moveCalendarToNextMonth { + NSDateComponents* comps = [[NSDateComponents alloc] init]; + [comps setMonth:1]; + NSDate *newMonth = [self.calendar dateByAddingComponents:comps toDate:self.monthShowing options:0]; + [self _moveCalendarToMonth:newMonth]; +} + - (void)_moveCalendarToPreviousMonth { NSDateComponents* comps = [[NSDateComponents alloc] init]; [comps setMonth:-1]; NSDate *newMonth = [self.calendar dateByAddingComponents:comps toDate:self.monthShowing options:0]; - if ([self.delegate respondsToSelector:@selector(calendar:willChangeToMonth:)] && ![self.delegate calendar:self willChangeToMonth:newMonth]) { - return; - } else { - self.monthShowing = newMonth; - if ([self.delegate respondsToSelector:@selector(calendar:didChangeToMonth:)] ) { - [self.delegate calendar:self didChangeToMonth:self.monthShowing]; - } - } + [self _moveCalendarToMonth:newMonth]; +} + +-(void) _moveCalendarToToday { + [self _moveCalendarToMonth:[NSDate date]]; } - (void)_dateButtonPressed:(id)sender { @@ -479,31 +528,38 @@ - (void)_dateButtonPressed:(id)sender { } else if ([self.delegate respondsToSelector:@selector(calendar:willSelectDate:)] && ![self.delegate calendar:self willSelectDate:date]) { return; } - + [self selectDate:date makeVisible:YES]; [self.delegate calendar:self didSelectDate:date]; [self setNeedsLayout]; } +-(void) setTitleButtonText:(NSString *) title { + [self.titleButton setTitle:title forState:UIControlStateNormal]; + [self.titleButton setTitle:title forState:UIControlStateHighlighted]; + [self.titleButton setTitle:title forState:UIControlStateSelected]; + [self.titleButton setTitle:title forState:UIControlStateDisabled]; +} + #pragma mark - Theming getters/setters - (void)setTitleFont:(UIFont *)font { - self.titleLabel.font = font; + self.titleButton.titleLabel.font = font; } - (UIFont *)titleFont { - return self.titleLabel.font; + return self.titleButton.titleLabel.font; } - (void)setTitleColor:(UIColor *)color { - self.titleLabel.textColor = color; + self.titleButton.titleLabel.textColor = color; } - (UIColor *)titleColor { - return self.titleLabel.textColor; + return self.titleButton.titleLabel.textColor; } - (void)setMonthButtonColor:(UIColor *)color { - [self.prevButton setImage:[CKCalendarView _imageNamed:@"left_arrow.png" withColor:color] forState:UIControlStateNormal]; - [self.nextButton setImage:[CKCalendarView _imageNamed:@"right_arrow.png" withColor:color] forState:UIControlStateNormal]; + [self.prevButton setImage:[CKCalendarView _arrowWithColor:color size:self.monthButtonSize style:ARROW_LEFT] forState:UIControlStateNormal]; + [self.nextButton setImage:[CKCalendarView _arrowWithColor:color size:self.monthButtonSize style:ARROW_RIGHT] forState:UIControlStateNormal]; } - (void)setInnerBorderColor:(UIColor *)color { @@ -548,6 +604,17 @@ - (UIColor *)dateBorderColor { return self.calendarContainer.backgroundColor; } +-(void)setMonthButtonSize:(CGSize) p_monthButtonSize { + _monthButtonSize = p_monthButtonSize; + + [self.prevButton setImage:[CKCalendarView _arrowWithColor:[UIColor whiteColor] size:_monthButtonSize style:ARROW_LEFT] forState:UIControlStateNormal]; + [self.nextButton setImage:[CKCalendarView _arrowWithColor:[UIColor whiteColor] size:_monthButtonSize style:ARROW_RIGHT] forState:UIControlStateNormal]; +} + +-(CGSize)monthButtonSize { + return _monthButtonSize; +} + #pragma mark - Calendar helpers - (NSDate *)_firstDayOfMonthContainingDate:(NSDate *)date { @@ -570,7 +637,7 @@ - (BOOL)dateIsInCurrentMonth:(NSDate *)date { - (NSComparisonResult)_compareByMonth:(NSDate *)date toDate:(NSDate *)otherDate { NSDateComponents *day = [self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:date]; NSDateComponents *day2 = [self.calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:otherDate]; - + if (day.year < day2.year) { return NSOrderedAscending; } else if (day.year > day2.year) { @@ -586,7 +653,12 @@ - (NSComparisonResult)_compareByMonth:(NSDate *)date toDate:(NSDate *)otherDate - (NSInteger)_placeInWeekForDate:(NSDate *)date { NSDateComponents *compsFirstDayInMonth = [self.calendar components:NSWeekdayCalendarUnit fromDate:date]; - return (compsFirstDayInMonth.weekday - 1 - self.calendar.firstWeekday + 8) % 7; + return (compsFirstDayInMonth.weekday - self.calendar.firstWeekday + 7) % 7; +} + +-(BOOL)_dateIsOffday:(NSDate *)date { + NSUInteger weekday = [self.calendar components:NSWeekdayCalendarUnit fromDate:date].weekday; + return [self.offDays containsObject:[NSNumber numberWithInt:weekday]]; } - (BOOL)_dateIsToday:(NSDate *)date { @@ -598,7 +670,7 @@ - (BOOL)date:(NSDate *)date1 isSameDayAsDate:(NSDate *)date2 { if (date1 == nil || date2 == nil) { return NO; } - + NSDateComponents *day = [self.calendar components:NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date1]; NSDateComponents *day2 = [self.calendar components:NSEraCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date2]; return ([day2 day] == [day day] && @@ -629,27 +701,46 @@ - (NSInteger)_numberOfDaysFromDate:(NSDate *)startDate toDate:(NSDate *)endDate return endDay - startDay; } -+ (UIImage *)_imageNamed:(NSString *)name withColor:(UIColor *)color { - UIImage *img = [UIImage imageNamed:name]; - - UIGraphicsBeginImageContextWithOptions(img.size, NO, [UIScreen mainScreen].scale); ++(UIImage *) _arrowWithColor:(UIColor *) color size:(CGSize) size style:(ARROW_STYLE) arrowStyle { + UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale); + CGContextRef context = UIGraphicsGetCurrentContext(); [color setFill]; - - CGContextTranslateCTM(context, 0, img.size.height); + + CGContextTranslateCTM(context, 0, size.height); CGContextScaleCTM(context, 1.0, -1.0); - - CGContextSetBlendMode(context, kCGBlendModeColorBurn); - CGRect rect = CGRectMake(0, 0, img.size.width, img.size.height); - CGContextDrawImage(context, rect, img.CGImage); - - CGContextClipToMask(context, rect, img.CGImage); - CGContextAddRect(context, rect); - CGContextDrawPath(context,kCGPathFill); - + + CGMutablePathRef path = CGPathCreateMutable(); + + switch (arrowStyle) { + case ARROW_LEFT: + CGPathMoveToPoint(path, NULL, 0, size.height/2); + CGPathAddLineToPoint(path, NULL, size.width, 0); + CGPathAddLineToPoint(path, NULL, size.width, size.height); + break; + case ARROW_RIGHT: + CGPathMoveToPoint(path, NULL, 0, 0); + CGPathAddLineToPoint(path, NULL, size.width, size.height/2); + CGPathAddLineToPoint(path, NULL, 0, size.height); + break; + case ARROW_NOTIFICATION: + CGPathMoveToPoint(path, NULL, 0, 0); + CGPathAddLineToPoint(path, NULL, size.width, size.height); + CGPathAddLineToPoint(path, NULL, 0, size.height); + break; + default: + break; + } + + CGPathCloseSubpath(path); + + CGContextSetFillColorWithColor(context, color.CGColor); + CGContextAddPath(context, path); + CGContextFillPath(context); + UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); - + return coloredImg; } diff --git a/Source/resources/left_arrow.png b/Source/resources/left_arrow.png deleted file mode 100644 index fd87d53..0000000 Binary files a/Source/resources/left_arrow.png and /dev/null differ diff --git a/Source/resources/left_arrow@2x.png b/Source/resources/left_arrow@2x.png deleted file mode 100644 index ccb26e9..0000000 Binary files a/Source/resources/left_arrow@2x.png and /dev/null differ diff --git a/Source/resources/right_arrow.png b/Source/resources/right_arrow.png deleted file mode 100644 index a2aaf96..0000000 Binary files a/Source/resources/right_arrow.png and /dev/null differ diff --git a/Source/resources/right_arrow@2x.png b/Source/resources/right_arrow@2x.png deleted file mode 100644 index d7fe1fb..0000000 Binary files a/Source/resources/right_arrow@2x.png and /dev/null differ