├── .CustomCalendar.podspec.swp ├── .gitignore ├── Classes ├── CalendarView.h └── CalendarView.m ├── CustomCalendar.podspec ├── LICENSE ├── README.md ├── Screenshots ├── Screenshot1.png └── Screenshot2.png ├── sampleCalendar.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── sampleCalendar.xccheckout │ └── xcuserdata │ │ └── jubinjacob.xcuserdatad │ │ └── WorkspaceSettings.xcsettings └── xcuserdata │ └── jubinjacob.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── sampleCalendar.xcscheme │ └── xcschememanagement.plist ├── sampleCalendar ├── Base.lproj │ └── Main.storyboard ├── CalendarAppDelegate.h ├── CalendarAppDelegate.m ├── CustomCalendarViewController.h ├── CustomCalendarViewController.m ├── DefaultCalendarViewController.h ├── DefaultCalendarViewController.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── 29@2x.png │ │ ├── 29@3x.png │ │ ├── 40@2x.png │ │ ├── 40@3x.png │ │ ├── 60@2x.png │ │ ├── 60@3x.png │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── LaunchScreen.xib ├── en.lproj │ └── InfoPlist.strings ├── main.m ├── sampleCalendar-Info.plist └── sampleCalendar-Prefix.pch └── sampleCalendarTests ├── en.lproj └── InfoPlist.strings ├── sampleCalendarTests-Info.plist └── sampleCalendarTests.m /.CustomCalendar.podspec.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jubinjacob19/CustomCalendar/0733809f51cf177ec50b1f501606522bc46db027/.CustomCalendar.podspec.swp -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.xcuserstate 3 | 4 | *.xcbkptlist 5 | 6 | *.plist 7 | 8 | *.xcscheme 9 | -------------------------------------------------------------------------------- /Classes/CalendarView.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #define RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1] 4 | 5 | 6 | #import 7 | 8 | 9 | @protocol CalendarDelegate; 10 | @protocol CalendarDataSource; 11 | 12 | 13 | @interface CalendarView : UIView 14 | 15 | -(void)showNextMonth; 16 | -(void)showPreviousMonth; 17 | 18 | @property (nonatomic,strong) NSDate *calendarDate; 19 | @property (nonatomic,weak) id delegate; 20 | @property (nonatomic,weak) id datasource; 21 | 22 | 23 | // Font 24 | @property (nonatomic, strong) UIFont * defaultFont; 25 | @property (nonatomic, strong) UIFont * titleFont; 26 | 27 | // Text color for month and weekday labels 28 | @property (nonatomic, strong) UIColor * monthAndDayTextColor; 29 | 30 | // Border 31 | @property (nonatomic, strong) UIColor * borderColor; 32 | @property (nonatomic, assign) NSInteger borderWidth; 33 | 34 | // Button color 35 | @property (nonatomic, strong) UIColor * dayBgColorWithoutData; 36 | @property (nonatomic, strong) UIColor * dayBgColorWithData; 37 | @property (nonatomic, strong) UIColor * dayBgColorSelected; 38 | @property (nonatomic, strong) UIColor * dayTxtColorWithoutData; 39 | @property (nonatomic, strong) UIColor * dayTxtColorWithData; 40 | @property (nonatomic, strong) UIColor * dayTxtColorSelected; 41 | 42 | // Allows or disallows the user to change month when tapping a day button from another month 43 | @property (nonatomic, assign) BOOL allowsChangeMonthByDayTap; 44 | @property (nonatomic, assign) BOOL allowsChangeMonthBySwipe; 45 | @property (nonatomic, assign) BOOL allowsChangeMonthByButtons; 46 | 47 | // origin of the calendar Array 48 | @property (nonatomic, assign) NSInteger originX; 49 | @property (nonatomic, assign) NSInteger originY; 50 | 51 | // "Change month" animations 52 | @property (nonatomic, assign) UIViewAnimationOptions nextMonthAnimation; 53 | @property (nonatomic, assign) UIViewAnimationOptions prevMonthAnimation; 54 | 55 | // Miscellaneous 56 | @property (nonatomic, assign) BOOL keepSelDayWhenMonthChange; 57 | @property (nonatomic, assign) BOOL hideMonthLabel; 58 | 59 | 60 | 61 | @end 62 | 63 | 64 | 65 | @protocol CalendarDelegate 66 | 67 | -(void)dayChangedToDate:(NSDate *)selectedDate; 68 | 69 | @optional 70 | -(BOOL)shouldChangeDayToDate:(NSDate *)selectedDate; 71 | 72 | -(void)setHeightNeeded:(NSInteger)heightNeeded; 73 | -(void)setMonthLabel:(NSString *)monthLabel; 74 | -(void)setEnabledForPrevMonthButton:(BOOL)enablePrev nextMonthButton:(BOOL)enableNext; 75 | 76 | @end 77 | 78 | 79 | 80 | @protocol CalendarDataSource 81 | 82 | -(BOOL)isDataForDate:(NSDate *)date; 83 | -(BOOL)canSwipeToDate:(NSDate *)date; 84 | 85 | @end -------------------------------------------------------------------------------- /Classes/CalendarView.m: -------------------------------------------------------------------------------- 1 | 2 | #import "CalendarView.h" 3 | 4 | @interface CalendarView() 5 | 6 | // Gregorian calendar 7 | @property (nonatomic, strong) NSCalendar *gregorian; 8 | 9 | // Selected day 10 | @property (nonatomic, strong) NSDate * selectedDate; 11 | 12 | // Width in point of a day button 13 | @property (nonatomic, assign) NSInteger dayWidth; 14 | 15 | // NSCalendarUnit for day, month, year and era. 16 | @property (nonatomic, assign) NSCalendarUnit dayInfoUnits; 17 | 18 | // Array of label of weekdays 19 | @property (nonatomic, strong) NSArray * weekDayNames; 20 | 21 | // View shake 22 | @property (nonatomic, assign) NSInteger shakes; 23 | @property (nonatomic, assign) NSInteger shakeDirection; 24 | 25 | // Gesture recognizers 26 | @property (nonatomic, strong) UISwipeGestureRecognizer * swipeleft; 27 | @property (nonatomic, strong) UISwipeGestureRecognizer * swipeRight; 28 | 29 | 30 | 31 | @end 32 | @implementation CalendarView 33 | 34 | #pragma mark - Init methods 35 | 36 | - (id)initWithFrame:(CGRect)frame 37 | { 38 | self = [super initWithFrame:frame]; 39 | if (self) 40 | { 41 | _dayWidth = frame.size.width/8; 42 | _originX = (frame.size.width - 7*_dayWidth)/2; 43 | _gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 44 | _borderWidth = 4; 45 | _originY = _dayWidth; 46 | _calendarDate = [NSDate date]; 47 | _dayInfoUnits = NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; 48 | 49 | _monthAndDayTextColor = [UIColor brownColor]; 50 | _dayBgColorWithoutData = [UIColor whiteColor]; 51 | _dayBgColorWithData = [UIColor whiteColor]; 52 | _dayBgColorSelected = [UIColor brownColor]; 53 | 54 | _dayTxtColorWithoutData = [UIColor brownColor];; 55 | _dayTxtColorWithData = [UIColor brownColor]; 56 | _dayTxtColorSelected = [UIColor whiteColor]; 57 | 58 | _borderColor = [UIColor brownColor]; 59 | _allowsChangeMonthByDayTap = NO; 60 | _allowsChangeMonthByButtons = NO; 61 | _allowsChangeMonthBySwipe = YES; 62 | _hideMonthLabel = NO; 63 | _keepSelDayWhenMonthChange = NO; 64 | 65 | _nextMonthAnimation = UIViewAnimationOptionTransitionCrossDissolve; 66 | _prevMonthAnimation = UIViewAnimationOptionTransitionCrossDissolve; 67 | 68 | _defaultFont = [UIFont fontWithName:@"HelveticaNeue" size:15.0f]; 69 | _titleFont = [UIFont fontWithName:@"Helvetica-Bold" size:15.0f]; 70 | 71 | 72 | _swipeleft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(showNextMonth)]; 73 | _swipeleft.direction=UISwipeGestureRecognizerDirectionLeft; 74 | [self addGestureRecognizer:_swipeleft]; 75 | _swipeRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(showPreviousMonth)]; 76 | _swipeRight.direction=UISwipeGestureRecognizerDirectionRight; 77 | [self addGestureRecognizer:_swipeRight]; 78 | 79 | NSDateComponents *components = [_gregorian components:_dayInfoUnits fromDate:[NSDate date]]; 80 | components.hour = 0; 81 | components.minute = 0; 82 | components.second = 0; 83 | 84 | _selectedDate = [_gregorian dateFromComponents:components]; 85 | 86 | NSArray * shortWeekdaySymbols = [[[NSDateFormatter alloc] init] shortWeekdaySymbols]; 87 | _weekDayNames = @[shortWeekdaySymbols[1], shortWeekdaySymbols[2], shortWeekdaySymbols[3], shortWeekdaySymbols[4], 88 | shortWeekdaySymbols[5], shortWeekdaySymbols[6], shortWeekdaySymbols[0]]; 89 | 90 | self.backgroundColor = [UIColor clearColor]; 91 | } 92 | return self; 93 | } 94 | 95 | -(id)init 96 | { 97 | self = [self initWithFrame:CGRectMake(0, 0, 320, 400)]; 98 | if (self) 99 | { 100 | 101 | } 102 | return self; 103 | } 104 | 105 | #pragma mark - Custom setters 106 | 107 | -(void)setAllowsChangeMonthByButtons:(BOOL)allows 108 | { 109 | _allowsChangeMonthByButtons = allows; 110 | [self setNeedsDisplay]; 111 | } 112 | 113 | -(void)setAllowsChangeMonthBySwipe:(BOOL)allows 114 | { 115 | _allowsChangeMonthBySwipe = allows; 116 | _swipeleft.enabled = allows; 117 | _swipeRight.enabled = allows; 118 | } 119 | 120 | -(void)setHideMonthLabel:(BOOL)hideMonthLabel 121 | { 122 | _hideMonthLabel = hideMonthLabel; 123 | [self setNeedsDisplay]; 124 | } 125 | 126 | -(void)setSelectedDate:(NSDate *)selectedDate 127 | { 128 | _selectedDate = selectedDate; 129 | [self setNeedsDisplay]; 130 | } 131 | 132 | -(void)setCalendarDate:(NSDate *)calendarDate 133 | { 134 | _calendarDate = calendarDate; 135 | [self setNeedsDisplay]; 136 | } 137 | 138 | 139 | #pragma mark - Public methods 140 | 141 | -(void)showNextMonth 142 | { 143 | NSDateComponents *components = [_gregorian components:_dayInfoUnits fromDate:_calendarDate]; 144 | components.day = 1; 145 | components.month ++; 146 | NSDate * nextMonthDate =[_gregorian dateFromComponents:components]; 147 | 148 | if ([self canSwipeToDate:nextMonthDate]) 149 | { 150 | [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 151 | _calendarDate = nextMonthDate; 152 | components = [_gregorian components:_dayInfoUnits fromDate:_calendarDate]; 153 | 154 | if (!_keepSelDayWhenMonthChange) 155 | { 156 | _selectedDate = [_gregorian dateFromComponents:components]; 157 | } 158 | [self performViewAnimation:_nextMonthAnimation]; 159 | } 160 | else 161 | { 162 | [self performViewNoSwipeAnimation]; 163 | } 164 | } 165 | 166 | 167 | -(void)showPreviousMonth 168 | { 169 | NSDateComponents *components = [_gregorian components:_dayInfoUnits fromDate:_calendarDate]; 170 | components.day = 1; 171 | components.month --; 172 | NSDate * prevMonthDate = [_gregorian dateFromComponents:components]; 173 | 174 | if ([self canSwipeToDate:prevMonthDate]) 175 | { 176 | [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 177 | _calendarDate = prevMonthDate; 178 | components = [_gregorian components:_dayInfoUnits fromDate:_calendarDate]; 179 | 180 | if (!_keepSelDayWhenMonthChange) 181 | { 182 | _selectedDate = [_gregorian dateFromComponents:components]; 183 | } 184 | [self performViewAnimation:_prevMonthAnimation]; 185 | } 186 | else 187 | { 188 | [self performViewNoSwipeAnimation]; 189 | } 190 | } 191 | 192 | #pragma mark - Various methods 193 | 194 | 195 | -(NSInteger)buttonTagForDate:(NSDate *)date 196 | { 197 | NSDateComponents * componentsDate = [_gregorian components:_dayInfoUnits fromDate:date]; 198 | NSDateComponents * componentsDateCal = [_gregorian components:_dayInfoUnits fromDate:_calendarDate]; 199 | 200 | if (componentsDate.month == componentsDateCal.month && componentsDate.year == componentsDateCal.year) 201 | { 202 | // Both dates are within the same month : buttonTag = day 203 | return componentsDate.day; 204 | } 205 | else 206 | { 207 | // buttonTag = deltaMonth * 40 + day 208 | NSInteger offsetMonth = (componentsDate.year - componentsDateCal.year)*12 + (componentsDate.month - componentsDateCal.month); 209 | return componentsDate.day + offsetMonth*40; 210 | } 211 | } 212 | 213 | -(BOOL)canSwipeToDate:(NSDate *)date 214 | { 215 | if (_datasource == nil) 216 | return YES; 217 | return [_datasource canSwipeToDate:date]; 218 | } 219 | 220 | -(BOOL)shouldChangeDayToDate:(NSDate *)date { 221 | if ([_delegate respondsToSelector:@selector(shouldChangeDayToDate:)]) { 222 | return [_delegate shouldChangeDayToDate:date]; 223 | } 224 | return YES; 225 | } 226 | 227 | -(void)performViewAnimation:(UIViewAnimationOptions)animation 228 | { 229 | NSDateComponents * components = [_gregorian components:_dayInfoUnits fromDate:_selectedDate]; 230 | 231 | NSDate *clickedDate = [_gregorian dateFromComponents:components]; 232 | [_delegate dayChangedToDate:clickedDate]; 233 | 234 | [UIView transitionWithView:self 235 | duration:0.5f 236 | options:animation 237 | animations:^ { [self setNeedsDisplay]; } 238 | completion:nil]; 239 | } 240 | 241 | -(void)performViewNoSwipeAnimation 242 | { 243 | _shakeDirection = 1; 244 | _shakes = 0; 245 | [self shakeView:self]; 246 | } 247 | 248 | // Taken from http://github.com/kosyloa/PinPad 249 | -(void)shakeView:(UIView *)theOneYouWannaShake 250 | { 251 | [UIView animateWithDuration:0.05 animations:^ 252 | { 253 | theOneYouWannaShake.transform = CGAffineTransformMakeTranslation(5*_shakeDirection, 0); 254 | 255 | } completion:^(BOOL finished) 256 | { 257 | if(_shakes >= 4) 258 | { 259 | theOneYouWannaShake.transform = CGAffineTransformIdentity; 260 | return; 261 | } 262 | _shakes++; 263 | _shakeDirection = _shakeDirection * -1; 264 | [self shakeView:theOneYouWannaShake]; 265 | }]; 266 | } 267 | 268 | #pragma mark - Button creation and configuration 269 | 270 | -(UIButton *)dayButtonWithFrame:(CGRect)frame 271 | { 272 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 273 | button.titleLabel.font = _defaultFont; 274 | button.frame = frame; 275 | button.layer.borderColor = _borderColor.CGColor; 276 | [button addTarget:self action:@selector(tappedDate:) forControlEvents:UIControlEventTouchUpInside]; 277 | return button; 278 | } 279 | 280 | -(void)configureDayButton:(UIButton *)button withDate:(NSDate*)date 281 | { 282 | NSDateComponents *components = [_gregorian components:_dayInfoUnits fromDate:date]; 283 | [button setTitle:[NSString stringWithFormat:@"%ld",(long)components.day] forState:UIControlStateNormal]; 284 | button.tag = [self buttonTagForDate:date]; 285 | 286 | if([_selectedDate compare:date] == NSOrderedSame) 287 | { 288 | // Selected button 289 | button.layer.borderWidth = 0; 290 | [button setTitleColor:_dayTxtColorSelected forState:UIControlStateNormal]; 291 | [button setBackgroundColor:_dayBgColorSelected]; 292 | } 293 | else 294 | { 295 | // Unselected button 296 | button.layer.borderWidth = _borderWidth/2.f; 297 | [button setTitleColor:_dayTxtColorWithoutData forState:UIControlStateNormal]; 298 | [button setBackgroundColor:_dayBgColorWithoutData]; 299 | 300 | if (_datasource != nil && [_datasource isDataForDate:date]) 301 | { 302 | [button setTitleColor:_dayTxtColorWithData forState:UIControlStateNormal]; 303 | [button setBackgroundColor:_dayBgColorWithData]; 304 | } 305 | } 306 | 307 | NSDateComponents * componentsDateCal = [_gregorian components:_dayInfoUnits fromDate:_calendarDate]; 308 | if (components.month != componentsDateCal.month) 309 | button.alpha = 0.6f; 310 | } 311 | 312 | #pragma mark - Action methods 313 | 314 | -(IBAction)tappedDate:(UIButton *)sender 315 | { 316 | NSDateComponents *components = [_gregorian components:_dayInfoUnits fromDate:_calendarDate]; 317 | 318 | if (sender.tag < 0 || sender.tag >= 40) 319 | { 320 | // The day tapped is in another month than the one currently displayed 321 | 322 | if (!_allowsChangeMonthByDayTap) 323 | return; 324 | 325 | NSInteger offsetMonth = (sender.tag < 0)?-1:1; 326 | NSInteger offsetTag = (sender.tag < 0)?40:-40; 327 | 328 | // otherMonthDate set to beginning of the next/previous month 329 | components.day = 1; 330 | components.month += offsetMonth; 331 | NSDate * otherMonthDate =[_gregorian dateFromComponents:components]; 332 | 333 | if ([self canSwipeToDate:otherMonthDate] || [self shouldChangeDayToDate:otherMonthDate]) 334 | { 335 | [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 336 | _calendarDate = otherMonthDate; 337 | 338 | // New selected date set to the day tapped 339 | components.day = sender.tag + offsetTag; 340 | _selectedDate = [_gregorian dateFromComponents:components]; 341 | 342 | UIViewAnimationOptions animation = (offsetMonth >0)?_nextMonthAnimation:_prevMonthAnimation; 343 | 344 | // Animate the transition 345 | [self performViewAnimation:animation]; 346 | } 347 | else 348 | { 349 | [self performViewNoSwipeAnimation]; 350 | } 351 | return; 352 | } 353 | 354 | // Day taped within the the displayed month 355 | NSDateComponents * componentsDateSel = [_gregorian components:_dayInfoUnits fromDate:_selectedDate]; 356 | if(componentsDateSel.day != sender.tag || componentsDateSel.month != components.month || componentsDateSel.year != components.year) 357 | { 358 | // Let's keep a backup of the old selectedDay 359 | NSDate * oldSelectedDate = [_selectedDate copy]; 360 | 361 | // We redifine the selected day 362 | componentsDateSel.day = sender.tag; 363 | componentsDateSel.month = components.month; 364 | componentsDateSel.year = components.year; 365 | _selectedDate = [_gregorian dateFromComponents:componentsDateSel]; 366 | 367 | // If returns NO, restore the old date and return 368 | if (![self shouldChangeDayToDate:_selectedDate]) { 369 | _selectedDate = oldSelectedDate; 370 | return; 371 | } 372 | 373 | // Configure the new selected day button 374 | [self configureDayButton:sender withDate:_selectedDate]; 375 | 376 | // Configure the previously selected button, if it's visible 377 | UIButton *previousSelected =(UIButton *) [self viewWithTag:[self buttonTagForDate:oldSelectedDate]]; 378 | if (previousSelected) 379 | [self configureDayButton:previousSelected withDate:oldSelectedDate]; 380 | 381 | // Finally, notify the delegate 382 | [_delegate dayChangedToDate:_selectedDate]; 383 | } 384 | } 385 | 386 | 387 | #pragma mark - Drawing methods 388 | 389 | - (void)drawRect:(CGRect)rect 390 | { 391 | NSDateComponents *components = [_gregorian components:_dayInfoUnits fromDate:_calendarDate]; 392 | 393 | components.day = 1; 394 | NSDate *firstDayOfMonth = [_gregorian dateFromComponents:components]; 395 | NSDateComponents *comps = [_gregorian components:NSWeekdayCalendarUnit fromDate:firstDayOfMonth]; 396 | 397 | NSInteger weekdayBeginning = [comps weekday]; // Starts at 1 on Sunday 398 | weekdayBeginning -=2; 399 | if(weekdayBeginning < 0) 400 | weekdayBeginning += 7; // Starts now at 0 on Monday 401 | 402 | NSRange days = [_gregorian rangeOfUnit:NSDayCalendarUnit 403 | inUnit:NSMonthCalendarUnit 404 | forDate:_calendarDate]; 405 | 406 | NSInteger monthLength = days.length; 407 | NSInteger remainingDays = (monthLength + weekdayBeginning) % 7; 408 | 409 | 410 | // Frame drawing 411 | NSInteger minY = _originY + _dayWidth; 412 | NSInteger maxY = _originY + _dayWidth * (NSInteger)(1+(monthLength+weekdayBeginning)/7) + ((remainingDays !=0)? _dayWidth:0); 413 | 414 | if (_delegate != nil && [_delegate respondsToSelector:@selector(setHeightNeeded:)]) 415 | [_delegate setHeightNeeded:maxY]; 416 | 417 | CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB(); 418 | CGContextRef context = UIGraphicsGetCurrentContext(); 419 | 420 | CGContextSetFillColorWithColor(context, _borderColor.CGColor); 421 | CGContextAddRect(context, CGRectMake(_originX - _borderWidth/2.f, minY - _borderWidth/2.f, 7*_dayWidth + _borderWidth, _borderWidth)); 422 | CGContextAddRect(context, CGRectMake(_originX - _borderWidth/2.f, maxY - _borderWidth/2.f, 7*_dayWidth + _borderWidth, _borderWidth)); 423 | CGContextAddRect(context, CGRectMake(_originX - _borderWidth/2.f, minY - _borderWidth/2.f, _borderWidth, maxY - minY)); 424 | CGContextAddRect(context, CGRectMake(_originX + 7*_dayWidth - _borderWidth/2.f, minY - _borderWidth/2.f, _borderWidth, maxY - minY)); 425 | CGContextFillPath(context); 426 | CGColorSpaceRelease(baseSpace), baseSpace = NULL; 427 | 428 | BOOL enableNext = YES; 429 | BOOL enablePrev = YES; 430 | 431 | // Previous and next button 432 | UIButton * buttonPrev = [[UIButton alloc] initWithFrame:CGRectMake(_originX, 0, _dayWidth, _dayWidth)]; 433 | [buttonPrev setTitle:@"<" forState:UIControlStateNormal]; 434 | [buttonPrev setTitleColor:_monthAndDayTextColor forState:UIControlStateNormal]; 435 | [buttonPrev addTarget:self action:@selector(showPreviousMonth) forControlEvents:UIControlEventTouchUpInside]; 436 | buttonPrev.titleLabel.font = _defaultFont; 437 | [self addSubview:buttonPrev]; 438 | 439 | UIButton * buttonNext = [[UIButton alloc] initWithFrame:CGRectMake(self.bounds.size.width - _dayWidth - _originX, 0, _dayWidth, _dayWidth)]; 440 | [buttonNext setTitle:@">" forState:UIControlStateNormal]; 441 | [buttonNext setTitleColor:_monthAndDayTextColor forState:UIControlStateNormal]; 442 | [buttonNext addTarget:self action:@selector(showNextMonth) forControlEvents:UIControlEventTouchUpInside]; 443 | buttonNext.titleLabel.font = _defaultFont; 444 | [self addSubview:buttonNext]; 445 | 446 | NSDateComponents *componentsTmp = [_gregorian components:_dayInfoUnits fromDate:_calendarDate]; 447 | componentsTmp.day = 1; 448 | componentsTmp.month --; 449 | NSDate * prevMonthDate =[_gregorian dateFromComponents:componentsTmp]; 450 | if (![self canSwipeToDate:prevMonthDate]) 451 | { 452 | buttonPrev.alpha = 0.5f; 453 | buttonPrev.enabled = NO; 454 | enablePrev = NO; 455 | } 456 | componentsTmp.month +=2; 457 | NSDate * nextMonthDate =[_gregorian dateFromComponents:componentsTmp]; 458 | if (![self canSwipeToDate:nextMonthDate]) 459 | { 460 | buttonNext.alpha = 0.5f; 461 | buttonNext.enabled = NO; 462 | enableNext = NO; 463 | } 464 | if (!_allowsChangeMonthByButtons) 465 | { 466 | buttonNext.hidden = YES; 467 | buttonPrev.hidden = YES; 468 | } 469 | if (_delegate != nil && [_delegate respondsToSelector:@selector(setEnabledForPrevMonthButton:nextMonthButton:)]) 470 | [_delegate setEnabledForPrevMonthButton:enablePrev nextMonthButton:enableNext]; 471 | 472 | // Month label 473 | NSDateFormatter *format = [[NSDateFormatter alloc] init]; 474 | [format setDateFormat:@"MMMM yyyy"]; 475 | NSString *dateString = [[format stringFromDate:_calendarDate] uppercaseString]; 476 | 477 | if (!_hideMonthLabel) 478 | { 479 | UILabel *titleText = [[UILabel alloc]initWithFrame:CGRectMake(0,0, self.bounds.size.width, _originY)]; 480 | titleText.textAlignment = NSTextAlignmentCenter; 481 | titleText.text = dateString; 482 | titleText.font = _titleFont; 483 | titleText.textColor = _monthAndDayTextColor; 484 | [self addSubview:titleText]; 485 | } 486 | 487 | if (_delegate != nil && [_delegate respondsToSelector:@selector(setMonthLabel:)]) 488 | [_delegate setMonthLabel:dateString]; 489 | 490 | // Day labels 491 | __block CGRect frameWeekLabel = CGRectMake(0, _originY, _dayWidth, _dayWidth); 492 | [_weekDayNames enumerateObjectsUsingBlock:^(NSString * dayOfWeekString, NSUInteger idx, BOOL *stop) 493 | { 494 | frameWeekLabel.origin.x = _originX+(_dayWidth*idx); 495 | UILabel *weekNameLabel = [[UILabel alloc] initWithFrame:frameWeekLabel]; 496 | weekNameLabel.text = dayOfWeekString; 497 | weekNameLabel.textColor = _monthAndDayTextColor; 498 | weekNameLabel.font = _defaultFont; 499 | weekNameLabel.backgroundColor = [UIColor clearColor]; 500 | weekNameLabel.textAlignment = NSTextAlignmentCenter; 501 | [self addSubview:weekNameLabel]; 502 | }]; 503 | 504 | // Current month 505 | for (NSInteger i= 0; i "MIT", :file => "LICENSE"} 13 | s.author = { "jubinjacob19" => "jubinjacob19@gmail.com" } 14 | s.platform = :ios 15 | s.ios.deployment_target = "7.0" 16 | s.frameworks = "UIKit", "CoreGraphics","Foundation" 17 | 18 | s.source = { :git => "https://github.com/jubinjacob19/CustomCalendar.git", :tag => "0.0.1", :commit => "636540bfec746244627c64bda0b0ac7391107119" } 19 | s.source_files = "SampleCalendar/*.{h,m}" 20 | s.requires_arc = true 21 | 22 | end 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) [2014] [Jubin Jacob] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (CustomCalendar), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CustomCalendar 2 | ============== 3 | 4 | ![Screenshot1](Screenshots/Screenshot1.png "Screenshot1") ![Screenshot2](Screenshots/Screenshot2.png "Screenshot2") 5 | 6 | 7 | Custom Calendar for iOS 8 | Grid Calendar view for iOS created by Jubin Jacob (jubinjacob19@gmail.com) 9 | Swipe to change months. 10 | 11 | Delegate displays selected date(NSDate) on selection of a date. 12 | 13 | Datasource allows some days to be highlighted and the calendar to be « locked » between a starting month and an ending month. 14 | 15 | Swift version added https://github.com/jubinjacob19/CustomCalendarSwift 16 | -------------------------------------------------------------------------------- /Screenshots/Screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jubinjacob19/CustomCalendar/0733809f51cf177ec50b1f501606522bc46db027/Screenshots/Screenshot1.png -------------------------------------------------------------------------------- /Screenshots/Screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jubinjacob19/CustomCalendar/0733809f51cf177ec50b1f501606522bc46db027/Screenshots/Screenshot2.png -------------------------------------------------------------------------------- /sampleCalendar.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 77A30EF11929B48400418A45 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77A30EF01929B48400418A45 /* Foundation.framework */; }; 11 | 77A30EF31929B48400418A45 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77A30EF21929B48400418A45 /* CoreGraphics.framework */; }; 12 | 77A30EF51929B48400418A45 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77A30EF41929B48400418A45 /* UIKit.framework */; }; 13 | 77A30EFB1929B48400418A45 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 77A30EF91929B48400418A45 /* InfoPlist.strings */; }; 14 | 77A30EFD1929B48400418A45 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 77A30EFC1929B48400418A45 /* main.m */; }; 15 | 77A30F011929B48400418A45 /* CalendarAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 77A30F001929B48400418A45 /* CalendarAppDelegate.m */; }; 16 | 77A30F041929B48400418A45 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 77A30F021929B48400418A45 /* Main.storyboard */; }; 17 | 77A30F091929B48400418A45 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 77A30F081929B48400418A45 /* Images.xcassets */; }; 18 | 77A30F101929B48400418A45 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77A30F0F1929B48400418A45 /* XCTest.framework */; }; 19 | 77A30F111929B48400418A45 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77A30EF01929B48400418A45 /* Foundation.framework */; }; 20 | 77A30F121929B48400418A45 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77A30EF41929B48400418A45 /* UIKit.framework */; }; 21 | 77A30F1A1929B48400418A45 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 77A30F181929B48400418A45 /* InfoPlist.strings */; }; 22 | 77A30F1C1929B48400418A45 /* sampleCalendarTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 77A30F1B1929B48400418A45 /* sampleCalendarTests.m */; }; 23 | 77A30F271929E6DB00418A45 /* DefaultCalendarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 77A30F261929E6DB00418A45 /* DefaultCalendarViewController.m */; }; 24 | 8372D05B197D380E006A64AC /* CustomCalendarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8372D05A197D380E006A64AC /* CustomCalendarViewController.m */; }; 25 | 8372D05E197D3D2D006A64AC /* CalendarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8372D05D197D3D2D006A64AC /* CalendarView.m */; }; 26 | F9A7F9B51A896421002249FC /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = F9A7F9B41A896421002249FC /* LaunchScreen.xib */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | 77A30F131929B48400418A45 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 77A30EE51929B48400418A45 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 77A30EEC1929B48400418A45; 35 | remoteInfo = sampleCalendar; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 77A30EED1929B48400418A45 /* sampleCalendar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = sampleCalendar.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 77A30EF01929B48400418A45 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 42 | 77A30EF21929B48400418A45 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 43 | 77A30EF41929B48400418A45 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 44 | 77A30EF81929B48400418A45 /* sampleCalendar-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "sampleCalendar-Info.plist"; sourceTree = ""; }; 45 | 77A30EFA1929B48400418A45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 46 | 77A30EFC1929B48400418A45 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 47 | 77A30EFE1929B48400418A45 /* sampleCalendar-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "sampleCalendar-Prefix.pch"; sourceTree = ""; }; 48 | 77A30EFF1929B48400418A45 /* CalendarAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CalendarAppDelegate.h; sourceTree = ""; }; 49 | 77A30F001929B48400418A45 /* CalendarAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CalendarAppDelegate.m; sourceTree = ""; }; 50 | 77A30F031929B48400418A45 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | 77A30F081929B48400418A45 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 52 | 77A30F0E1929B48400418A45 /* sampleCalendarTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = sampleCalendarTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 77A30F0F1929B48400418A45 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 54 | 77A30F171929B48400418A45 /* sampleCalendarTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "sampleCalendarTests-Info.plist"; sourceTree = ""; }; 55 | 77A30F191929B48400418A45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 56 | 77A30F1B1929B48400418A45 /* sampleCalendarTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = sampleCalendarTests.m; sourceTree = ""; }; 57 | 77A30F251929E6DB00418A45 /* DefaultCalendarViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DefaultCalendarViewController.h; sourceTree = ""; }; 58 | 77A30F261929E6DB00418A45 /* DefaultCalendarViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DefaultCalendarViewController.m; sourceTree = ""; }; 59 | 8372D059197D380E006A64AC /* CustomCalendarViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomCalendarViewController.h; sourceTree = ""; }; 60 | 8372D05A197D380E006A64AC /* CustomCalendarViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomCalendarViewController.m; sourceTree = ""; }; 61 | 8372D05C197D3D2D006A64AC /* CalendarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CalendarView.h; path = Classes/CalendarView.h; sourceTree = SOURCE_ROOT; }; 62 | 8372D05D197D3D2D006A64AC /* CalendarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CalendarView.m; path = Classes/CalendarView.m; sourceTree = SOURCE_ROOT; }; 63 | F9A7F9B41A896421002249FC /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; 64 | /* End PBXFileReference section */ 65 | 66 | /* Begin PBXFrameworksBuildPhase section */ 67 | 77A30EEA1929B48400418A45 /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | 77A30EF31929B48400418A45 /* CoreGraphics.framework in Frameworks */, 72 | 77A30EF51929B48400418A45 /* UIKit.framework in Frameworks */, 73 | 77A30EF11929B48400418A45 /* Foundation.framework in Frameworks */, 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | 77A30F0B1929B48400418A45 /* Frameworks */ = { 78 | isa = PBXFrameworksBuildPhase; 79 | buildActionMask = 2147483647; 80 | files = ( 81 | 77A30F101929B48400418A45 /* XCTest.framework in Frameworks */, 82 | 77A30F121929B48400418A45 /* UIKit.framework in Frameworks */, 83 | 77A30F111929B48400418A45 /* Foundation.framework in Frameworks */, 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | /* End PBXFrameworksBuildPhase section */ 88 | 89 | /* Begin PBXGroup section */ 90 | 77A30EE41929B48400418A45 = { 91 | isa = PBXGroup; 92 | children = ( 93 | 77A30EF61929B48400418A45 /* sampleCalendar */, 94 | 77A30F151929B48400418A45 /* sampleCalendarTests */, 95 | 77A30EEF1929B48400418A45 /* Frameworks */, 96 | 77A30EEE1929B48400418A45 /* Products */, 97 | ); 98 | sourceTree = ""; 99 | }; 100 | 77A30EEE1929B48400418A45 /* Products */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 77A30EED1929B48400418A45 /* sampleCalendar.app */, 104 | 77A30F0E1929B48400418A45 /* sampleCalendarTests.xctest */, 105 | ); 106 | name = Products; 107 | sourceTree = ""; 108 | }; 109 | 77A30EEF1929B48400418A45 /* Frameworks */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 77A30EF01929B48400418A45 /* Foundation.framework */, 113 | 77A30EF21929B48400418A45 /* CoreGraphics.framework */, 114 | 77A30EF41929B48400418A45 /* UIKit.framework */, 115 | 77A30F0F1929B48400418A45 /* XCTest.framework */, 116 | ); 117 | name = Frameworks; 118 | sourceTree = ""; 119 | }; 120 | 77A30EF61929B48400418A45 /* sampleCalendar */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 77A30EFF1929B48400418A45 /* CalendarAppDelegate.h */, 124 | 77A30F001929B48400418A45 /* CalendarAppDelegate.m */, 125 | 77A30F021929B48400418A45 /* Main.storyboard */, 126 | F9A7F9B41A896421002249FC /* LaunchScreen.xib */, 127 | 77A30F251929E6DB00418A45 /* DefaultCalendarViewController.h */, 128 | 77A30F261929E6DB00418A45 /* DefaultCalendarViewController.m */, 129 | 8372D059197D380E006A64AC /* CustomCalendarViewController.h */, 130 | 8372D05A197D380E006A64AC /* CustomCalendarViewController.m */, 131 | 8372D05C197D3D2D006A64AC /* CalendarView.h */, 132 | 8372D05D197D3D2D006A64AC /* CalendarView.m */, 133 | 77A30F081929B48400418A45 /* Images.xcassets */, 134 | 77A30EF71929B48400418A45 /* Supporting Files */, 135 | ); 136 | path = sampleCalendar; 137 | sourceTree = ""; 138 | }; 139 | 77A30EF71929B48400418A45 /* Supporting Files */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 77A30EF81929B48400418A45 /* sampleCalendar-Info.plist */, 143 | 77A30EF91929B48400418A45 /* InfoPlist.strings */, 144 | 77A30EFC1929B48400418A45 /* main.m */, 145 | 77A30EFE1929B48400418A45 /* sampleCalendar-Prefix.pch */, 146 | ); 147 | name = "Supporting Files"; 148 | sourceTree = ""; 149 | }; 150 | 77A30F151929B48400418A45 /* sampleCalendarTests */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 77A30F1B1929B48400418A45 /* sampleCalendarTests.m */, 154 | 77A30F161929B48400418A45 /* Supporting Files */, 155 | ); 156 | path = sampleCalendarTests; 157 | sourceTree = ""; 158 | }; 159 | 77A30F161929B48400418A45 /* Supporting Files */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 77A30F171929B48400418A45 /* sampleCalendarTests-Info.plist */, 163 | 77A30F181929B48400418A45 /* InfoPlist.strings */, 164 | ); 165 | name = "Supporting Files"; 166 | sourceTree = ""; 167 | }; 168 | /* End PBXGroup section */ 169 | 170 | /* Begin PBXNativeTarget section */ 171 | 77A30EEC1929B48400418A45 /* sampleCalendar */ = { 172 | isa = PBXNativeTarget; 173 | buildConfigurationList = 77A30F1F1929B48400418A45 /* Build configuration list for PBXNativeTarget "sampleCalendar" */; 174 | buildPhases = ( 175 | 77A30EE91929B48400418A45 /* Sources */, 176 | 77A30EEA1929B48400418A45 /* Frameworks */, 177 | 77A30EEB1929B48400418A45 /* Resources */, 178 | ); 179 | buildRules = ( 180 | ); 181 | dependencies = ( 182 | ); 183 | name = sampleCalendar; 184 | productName = sampleCalendar; 185 | productReference = 77A30EED1929B48400418A45 /* sampleCalendar.app */; 186 | productType = "com.apple.product-type.application"; 187 | }; 188 | 77A30F0D1929B48400418A45 /* sampleCalendarTests */ = { 189 | isa = PBXNativeTarget; 190 | buildConfigurationList = 77A30F221929B48400418A45 /* Build configuration list for PBXNativeTarget "sampleCalendarTests" */; 191 | buildPhases = ( 192 | 77A30F0A1929B48400418A45 /* Sources */, 193 | 77A30F0B1929B48400418A45 /* Frameworks */, 194 | 77A30F0C1929B48400418A45 /* Resources */, 195 | ); 196 | buildRules = ( 197 | ); 198 | dependencies = ( 199 | 77A30F141929B48400418A45 /* PBXTargetDependency */, 200 | ); 201 | name = sampleCalendarTests; 202 | productName = sampleCalendarTests; 203 | productReference = 77A30F0E1929B48400418A45 /* sampleCalendarTests.xctest */; 204 | productType = "com.apple.product-type.bundle.unit-test"; 205 | }; 206 | /* End PBXNativeTarget section */ 207 | 208 | /* Begin PBXProject section */ 209 | 77A30EE51929B48400418A45 /* Project object */ = { 210 | isa = PBXProject; 211 | attributes = { 212 | CLASSPREFIX = Sample; 213 | LastUpgradeCheck = 0510; 214 | ORGANIZATIONNAME = Attinad; 215 | TargetAttributes = { 216 | 77A30F0D1929B48400418A45 = { 217 | TestTargetID = 77A30EEC1929B48400418A45; 218 | }; 219 | }; 220 | }; 221 | buildConfigurationList = 77A30EE81929B48400418A45 /* Build configuration list for PBXProject "sampleCalendar" */; 222 | compatibilityVersion = "Xcode 3.2"; 223 | developmentRegion = English; 224 | hasScannedForEncodings = 0; 225 | knownRegions = ( 226 | en, 227 | Base, 228 | ); 229 | mainGroup = 77A30EE41929B48400418A45; 230 | productRefGroup = 77A30EEE1929B48400418A45 /* Products */; 231 | projectDirPath = ""; 232 | projectRoot = ""; 233 | targets = ( 234 | 77A30EEC1929B48400418A45 /* sampleCalendar */, 235 | 77A30F0D1929B48400418A45 /* sampleCalendarTests */, 236 | ); 237 | }; 238 | /* End PBXProject section */ 239 | 240 | /* Begin PBXResourcesBuildPhase section */ 241 | 77A30EEB1929B48400418A45 /* Resources */ = { 242 | isa = PBXResourcesBuildPhase; 243 | buildActionMask = 2147483647; 244 | files = ( 245 | F9A7F9B51A896421002249FC /* LaunchScreen.xib in Resources */, 246 | 77A30F091929B48400418A45 /* Images.xcassets in Resources */, 247 | 77A30EFB1929B48400418A45 /* InfoPlist.strings in Resources */, 248 | 77A30F041929B48400418A45 /* Main.storyboard in Resources */, 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | }; 252 | 77A30F0C1929B48400418A45 /* Resources */ = { 253 | isa = PBXResourcesBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | 77A30F1A1929B48400418A45 /* InfoPlist.strings in Resources */, 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | }; 260 | /* End PBXResourcesBuildPhase section */ 261 | 262 | /* Begin PBXSourcesBuildPhase section */ 263 | 77A30EE91929B48400418A45 /* Sources */ = { 264 | isa = PBXSourcesBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | 8372D05B197D380E006A64AC /* CustomCalendarViewController.m in Sources */, 268 | 77A30F271929E6DB00418A45 /* DefaultCalendarViewController.m in Sources */, 269 | 77A30F011929B48400418A45 /* CalendarAppDelegate.m in Sources */, 270 | 77A30EFD1929B48400418A45 /* main.m in Sources */, 271 | 8372D05E197D3D2D006A64AC /* CalendarView.m in Sources */, 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | 77A30F0A1929B48400418A45 /* Sources */ = { 276 | isa = PBXSourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | 77A30F1C1929B48400418A45 /* sampleCalendarTests.m in Sources */, 280 | ); 281 | runOnlyForDeploymentPostprocessing = 0; 282 | }; 283 | /* End PBXSourcesBuildPhase section */ 284 | 285 | /* Begin PBXTargetDependency section */ 286 | 77A30F141929B48400418A45 /* PBXTargetDependency */ = { 287 | isa = PBXTargetDependency; 288 | target = 77A30EEC1929B48400418A45 /* sampleCalendar */; 289 | targetProxy = 77A30F131929B48400418A45 /* PBXContainerItemProxy */; 290 | }; 291 | /* End PBXTargetDependency section */ 292 | 293 | /* Begin PBXVariantGroup section */ 294 | 77A30EF91929B48400418A45 /* InfoPlist.strings */ = { 295 | isa = PBXVariantGroup; 296 | children = ( 297 | 77A30EFA1929B48400418A45 /* en */, 298 | ); 299 | name = InfoPlist.strings; 300 | sourceTree = ""; 301 | }; 302 | 77A30F021929B48400418A45 /* Main.storyboard */ = { 303 | isa = PBXVariantGroup; 304 | children = ( 305 | 77A30F031929B48400418A45 /* Base */, 306 | ); 307 | name = Main.storyboard; 308 | sourceTree = ""; 309 | }; 310 | 77A30F181929B48400418A45 /* InfoPlist.strings */ = { 311 | isa = PBXVariantGroup; 312 | children = ( 313 | 77A30F191929B48400418A45 /* en */, 314 | ); 315 | name = InfoPlist.strings; 316 | sourceTree = ""; 317 | }; 318 | /* End PBXVariantGroup section */ 319 | 320 | /* Begin XCBuildConfiguration section */ 321 | 77A30F1D1929B48400418A45 /* Debug */ = { 322 | isa = XCBuildConfiguration; 323 | buildSettings = { 324 | ALWAYS_SEARCH_USER_PATHS = NO; 325 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 326 | CLANG_CXX_LIBRARY = "libc++"; 327 | CLANG_ENABLE_MODULES = YES; 328 | CLANG_ENABLE_OBJC_ARC = YES; 329 | CLANG_WARN_BOOL_CONVERSION = YES; 330 | CLANG_WARN_CONSTANT_CONVERSION = YES; 331 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 332 | CLANG_WARN_EMPTY_BODY = YES; 333 | CLANG_WARN_ENUM_CONVERSION = YES; 334 | CLANG_WARN_INT_CONVERSION = YES; 335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 336 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 337 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 338 | COPY_PHASE_STRIP = NO; 339 | GCC_C_LANGUAGE_STANDARD = gnu99; 340 | GCC_DYNAMIC_NO_PIC = NO; 341 | GCC_OPTIMIZATION_LEVEL = 0; 342 | GCC_PREPROCESSOR_DEFINITIONS = ( 343 | "DEBUG=1", 344 | "$(inherited)", 345 | ); 346 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 347 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 348 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 349 | GCC_WARN_UNDECLARED_SELECTOR = YES; 350 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 351 | GCC_WARN_UNUSED_FUNCTION = YES; 352 | GCC_WARN_UNUSED_VARIABLE = YES; 353 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 354 | ONLY_ACTIVE_ARCH = YES; 355 | SDKROOT = iphoneos; 356 | }; 357 | name = Debug; 358 | }; 359 | 77A30F1E1929B48400418A45 /* Release */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ALWAYS_SEARCH_USER_PATHS = NO; 363 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 364 | CLANG_CXX_LIBRARY = "libc++"; 365 | CLANG_ENABLE_MODULES = YES; 366 | CLANG_ENABLE_OBJC_ARC = YES; 367 | CLANG_WARN_BOOL_CONVERSION = YES; 368 | CLANG_WARN_CONSTANT_CONVERSION = YES; 369 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 370 | CLANG_WARN_EMPTY_BODY = YES; 371 | CLANG_WARN_ENUM_CONVERSION = YES; 372 | CLANG_WARN_INT_CONVERSION = YES; 373 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 374 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 375 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 376 | COPY_PHASE_STRIP = YES; 377 | ENABLE_NS_ASSERTIONS = NO; 378 | GCC_C_LANGUAGE_STANDARD = gnu99; 379 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 380 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 381 | GCC_WARN_UNDECLARED_SELECTOR = YES; 382 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 383 | GCC_WARN_UNUSED_FUNCTION = YES; 384 | GCC_WARN_UNUSED_VARIABLE = YES; 385 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 386 | SDKROOT = iphoneos; 387 | VALIDATE_PRODUCT = YES; 388 | }; 389 | name = Release; 390 | }; 391 | 77A30F201929B48400418A45 /* Debug */ = { 392 | isa = XCBuildConfiguration; 393 | buildSettings = { 394 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 395 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 396 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 397 | GCC_PREFIX_HEADER = "sampleCalendar/sampleCalendar-Prefix.pch"; 398 | INFOPLIST_FILE = "sampleCalendar/sampleCalendar-Info.plist"; 399 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 400 | PRODUCT_NAME = "$(TARGET_NAME)"; 401 | WRAPPER_EXTENSION = app; 402 | }; 403 | name = Debug; 404 | }; 405 | 77A30F211929B48400418A45 /* Release */ = { 406 | isa = XCBuildConfiguration; 407 | buildSettings = { 408 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 409 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 410 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 411 | GCC_PREFIX_HEADER = "sampleCalendar/sampleCalendar-Prefix.pch"; 412 | INFOPLIST_FILE = "sampleCalendar/sampleCalendar-Info.plist"; 413 | IPHONEOS_DEPLOYMENT_TARGET = 6.1; 414 | PRODUCT_NAME = "$(TARGET_NAME)"; 415 | WRAPPER_EXTENSION = app; 416 | }; 417 | name = Release; 418 | }; 419 | 77A30F231929B48400418A45 /* Debug */ = { 420 | isa = XCBuildConfiguration; 421 | buildSettings = { 422 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/sampleCalendar.app/sampleCalendar"; 423 | FRAMEWORK_SEARCH_PATHS = ( 424 | "$(SDKROOT)/Developer/Library/Frameworks", 425 | "$(inherited)", 426 | "$(DEVELOPER_FRAMEWORKS_DIR)", 427 | ); 428 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 429 | GCC_PREFIX_HEADER = "sampleCalendar/sampleCalendar-Prefix.pch"; 430 | GCC_PREPROCESSOR_DEFINITIONS = ( 431 | "DEBUG=1", 432 | "$(inherited)", 433 | ); 434 | INFOPLIST_FILE = "sampleCalendarTests/sampleCalendarTests-Info.plist"; 435 | PRODUCT_NAME = "$(TARGET_NAME)"; 436 | TEST_HOST = "$(BUNDLE_LOADER)"; 437 | WRAPPER_EXTENSION = xctest; 438 | }; 439 | name = Debug; 440 | }; 441 | 77A30F241929B48400418A45 /* Release */ = { 442 | isa = XCBuildConfiguration; 443 | buildSettings = { 444 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/sampleCalendar.app/sampleCalendar"; 445 | FRAMEWORK_SEARCH_PATHS = ( 446 | "$(SDKROOT)/Developer/Library/Frameworks", 447 | "$(inherited)", 448 | "$(DEVELOPER_FRAMEWORKS_DIR)", 449 | ); 450 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 451 | GCC_PREFIX_HEADER = "sampleCalendar/sampleCalendar-Prefix.pch"; 452 | INFOPLIST_FILE = "sampleCalendarTests/sampleCalendarTests-Info.plist"; 453 | PRODUCT_NAME = "$(TARGET_NAME)"; 454 | TEST_HOST = "$(BUNDLE_LOADER)"; 455 | WRAPPER_EXTENSION = xctest; 456 | }; 457 | name = Release; 458 | }; 459 | /* End XCBuildConfiguration section */ 460 | 461 | /* Begin XCConfigurationList section */ 462 | 77A30EE81929B48400418A45 /* Build configuration list for PBXProject "sampleCalendar" */ = { 463 | isa = XCConfigurationList; 464 | buildConfigurations = ( 465 | 77A30F1D1929B48400418A45 /* Debug */, 466 | 77A30F1E1929B48400418A45 /* Release */, 467 | ); 468 | defaultConfigurationIsVisible = 0; 469 | defaultConfigurationName = Release; 470 | }; 471 | 77A30F1F1929B48400418A45 /* Build configuration list for PBXNativeTarget "sampleCalendar" */ = { 472 | isa = XCConfigurationList; 473 | buildConfigurations = ( 474 | 77A30F201929B48400418A45 /* Debug */, 475 | 77A30F211929B48400418A45 /* Release */, 476 | ); 477 | defaultConfigurationIsVisible = 0; 478 | defaultConfigurationName = Release; 479 | }; 480 | 77A30F221929B48400418A45 /* Build configuration list for PBXNativeTarget "sampleCalendarTests" */ = { 481 | isa = XCConfigurationList; 482 | buildConfigurations = ( 483 | 77A30F231929B48400418A45 /* Debug */, 484 | 77A30F241929B48400418A45 /* Release */, 485 | ); 486 | defaultConfigurationIsVisible = 0; 487 | defaultConfigurationName = Release; 488 | }; 489 | /* End XCConfigurationList section */ 490 | }; 491 | rootObject = 77A30EE51929B48400418A45 /* Project object */; 492 | } 493 | -------------------------------------------------------------------------------- /sampleCalendar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sampleCalendar.xcodeproj/project.xcworkspace/xcshareddata/sampleCalendar.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 7202CB21-2E3A-4638-8705-3E0B11E915C0 9 | IDESourceControlProjectName 10 | sampleCalendar 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | DE21B0E0F08FFD5CC7F93ACCB95D79672DEE800A 14 | https://github.com/micazeve/CustomCalendar.git 15 | 16 | IDESourceControlProjectPath 17 | sampleCalendar.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | DE21B0E0F08FFD5CC7F93ACCB95D79672DEE800A 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/micazeve/CustomCalendar.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | DE21B0E0F08FFD5CC7F93ACCB95D79672DEE800A 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | DE21B0E0F08FFD5CC7F93ACCB95D79672DEE800A 36 | IDESourceControlWCCName 37 | CustomCalendar 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /sampleCalendar.xcodeproj/project.xcworkspace/xcuserdata/jubinjacob.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sampleCalendar.xcodeproj/xcuserdata/jubinjacob.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /sampleCalendar.xcodeproj/xcuserdata/jubinjacob.xcuserdatad/xcschemes/sampleCalendar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /sampleCalendar.xcodeproj/xcuserdata/jubinjacob.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | sampleCalendar.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 77A30EEC1929B48400418A45 16 | 17 | primary 18 | 19 | 20 | 77A30F0D1929B48400418A45 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /sampleCalendar/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 48 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /sampleCalendar/CalendarAppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface CalendarAppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /sampleCalendar/CalendarAppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "CalendarAppDelegate.h" 2 | 3 | @implementation CalendarAppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 6 | { 7 | // Override point for customization after application launch. 8 | return YES; 9 | } 10 | 11 | - (void)applicationWillResignActive:(UIApplication *)application 12 | { 13 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 14 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 15 | } 16 | 17 | - (void)applicationDidEnterBackground:(UIApplication *)application 18 | { 19 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 20 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 21 | } 22 | 23 | - (void)applicationWillEnterForeground:(UIApplication *)application 24 | { 25 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 26 | } 27 | 28 | - (void)applicationDidBecomeActive:(UIApplication *)application 29 | { 30 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 31 | } 32 | 33 | - (void)applicationWillTerminate:(UIApplication *)application 34 | { 35 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 36 | } 37 | 38 | - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 39 | { 40 | return UIInterfaceOrientationMaskPortrait; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /sampleCalendar/CustomCalendarViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCalendarViewController.h 3 | // sampleCalendar 4 | // 5 | // Created by Michael Azevedo on 21/07/2014. 6 | // Copyright (c) 2014 Michael Azevedo All rights reserved. 7 | // 8 | 9 | #import 10 | #import "CalendarView.h" 11 | 12 | @interface CustomCalendarViewController : UIViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /sampleCalendar/CustomCalendarViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCalendarViewController.h 3 | // sampleCalendar 4 | // 5 | // Created by Michael Azevedo on 21/07/2014. 6 | // Copyright (c) 2014 Michael Azevedo All rights reserved. 7 | // 8 | 9 | #import "CustomCalendarViewController.h" 10 | 11 | @interface CustomCalendarViewController () 12 | 13 | @property (nonatomic, strong) CalendarView * customCalendarView; 14 | @property (nonatomic, strong) NSCalendar * gregorian; 15 | @property (nonatomic, assign) NSInteger currentYear; 16 | 17 | @end 18 | 19 | @implementation CustomCalendarViewController 20 | 21 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 22 | { 23 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 24 | if (self) { 25 | // Custom initialization 26 | } 27 | return self; 28 | } 29 | 30 | - (void)viewDidLoad 31 | { 32 | 33 | [super viewDidLoad]; 34 | [self.view setBackgroundColor:[UIColor whiteColor]]; 35 | 36 | self.title = @"Custom Calendar"; 37 | 38 | _gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 39 | 40 | _customCalendarView = [[CalendarView alloc]initWithFrame:CGRectMake(0, 40, 320, 360)]; 41 | _customCalendarView.delegate = self; 42 | _customCalendarView.datasource = self; 43 | _customCalendarView.calendarDate = [NSDate date]; 44 | _customCalendarView.monthAndDayTextColor = RGBCOLOR(0, 174, 255); 45 | _customCalendarView.dayBgColorWithData = RGBCOLOR(21, 124, 229); 46 | _customCalendarView.dayBgColorWithoutData = RGBCOLOR(208, 208, 214); 47 | _customCalendarView.dayBgColorSelected = RGBCOLOR(94, 94, 94); 48 | _customCalendarView.dayTxtColorWithoutData = RGBCOLOR(57, 69, 84); 49 | _customCalendarView.dayTxtColorWithData = [UIColor whiteColor]; 50 | _customCalendarView.dayTxtColorSelected = [UIColor whiteColor]; 51 | _customCalendarView.borderColor = RGBCOLOR(159, 162, 172); 52 | _customCalendarView.borderWidth = 1; 53 | _customCalendarView.allowsChangeMonthByDayTap = YES; 54 | _customCalendarView.allowsChangeMonthByButtons = YES; 55 | _customCalendarView.keepSelDayWhenMonthChange = YES; 56 | _customCalendarView.nextMonthAnimation = UIViewAnimationOptionTransitionFlipFromRight; 57 | _customCalendarView.prevMonthAnimation = UIViewAnimationOptionTransitionFlipFromLeft; 58 | 59 | dispatch_async(dispatch_get_main_queue(), ^{ 60 | [self.view addSubview:_customCalendarView]; 61 | _customCalendarView.center = CGPointMake(self.view.center.x, _customCalendarView.center.y); 62 | }); 63 | 64 | NSDateComponents * yearComponent = [_gregorian components:NSYearCalendarUnit fromDate:[NSDate date]]; 65 | _currentYear = yearComponent.year; 66 | 67 | } 68 | 69 | #pragma mark - Gesture recognizer 70 | 71 | -(void)swipeleft:(id)sender 72 | { 73 | [_customCalendarView showNextMonth]; 74 | } 75 | 76 | -(void)swiperight:(id)sender 77 | { 78 | [_customCalendarView showPreviousMonth]; 79 | } 80 | 81 | #pragma mark - CalendarDelegate protocol conformance 82 | 83 | -(void)dayChangedToDate:(NSDate *)selectedDate 84 | { 85 | NSLog(@"dayChangedToDate %@(GMT)",selectedDate); 86 | } 87 | 88 | #pragma mark - CalendarDataSource protocol conformance 89 | 90 | -(BOOL)isDataForDate:(NSDate *)date 91 | { 92 | if ([date compare:[NSDate date]] == NSOrderedAscending) 93 | return YES; 94 | return NO; 95 | } 96 | 97 | -(BOOL)canSwipeToDate:(NSDate *)date 98 | { 99 | NSDateComponents * yearComponent = [_gregorian components:NSYearCalendarUnit fromDate:date]; 100 | return (yearComponent.year == _currentYear || yearComponent.year == _currentYear+1); 101 | } 102 | 103 | #pragma mark - Action methods 104 | 105 | - (void)didReceiveMemoryWarning 106 | { 107 | [super didReceiveMemoryWarning]; 108 | // Dispose of any resources that can be recreated. 109 | } 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /sampleCalendar/DefaultCalendarViewController.h: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | #import "CalendarView.h" 4 | 5 | @interface DefaultCalendarViewController : UIViewController 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /sampleCalendar/DefaultCalendarViewController.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | #import "DefaultCalendarViewController.h" 4 | 5 | 6 | @interface DefaultCalendarViewController () 7 | 8 | @property (nonatomic, strong) CalendarView * sampleView; 9 | 10 | @end 11 | 12 | 13 | @implementation DefaultCalendarViewController 14 | 15 | #pragma mark - Init methods 16 | 17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 18 | { 19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 20 | if (self) { 21 | // Custom initialization 22 | } 23 | return self; 24 | } 25 | 26 | - (void)viewDidLoad 27 | { 28 | 29 | [super viewDidLoad]; 30 | [self.view setBackgroundColor:[UIColor whiteColor]]; 31 | 32 | self.title = @"Default Calendar"; 33 | 34 | _sampleView= [[CalendarView alloc]initWithFrame:CGRectMake(0, 40, 320, 360)]; 35 | _sampleView.delegate = self; 36 | _sampleView.calendarDate = [NSDate date]; 37 | 38 | dispatch_async(dispatch_get_main_queue(), ^{ 39 | [self.view addSubview:_sampleView]; 40 | _sampleView.center = CGPointMake(self.view.center.x, _sampleView.center.y); 41 | }); 42 | } 43 | 44 | #pragma mark - CalendarDelegate protocol conformance 45 | 46 | -(void)dayChangedToDate:(NSDate *)selectedDate 47 | { 48 | NSLog(@"dayChangedToDate %@(GMT)",selectedDate); 49 | } 50 | 51 | -(BOOL)shouldChangeDayToDate:(NSDate *)selectedDate 52 | { 53 | if ([[NSDate date] compare:selectedDate] == NSOrderedAscending) { 54 | return YES; 55 | } 56 | return NO; 57 | } 58 | #pragma mark - Action methods 59 | 60 | - (void)didReceiveMemoryWarning 61 | { 62 | [super didReceiveMemoryWarning]; 63 | // Dispose of any resources that can be recreated. 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /sampleCalendar/Images.xcassets/AppIcon.appiconset/29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jubinjacob19/CustomCalendar/0733809f51cf177ec50b1f501606522bc46db027/sampleCalendar/Images.xcassets/AppIcon.appiconset/29@2x.png -------------------------------------------------------------------------------- /sampleCalendar/Images.xcassets/AppIcon.appiconset/29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jubinjacob19/CustomCalendar/0733809f51cf177ec50b1f501606522bc46db027/sampleCalendar/Images.xcassets/AppIcon.appiconset/29@3x.png -------------------------------------------------------------------------------- /sampleCalendar/Images.xcassets/AppIcon.appiconset/40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jubinjacob19/CustomCalendar/0733809f51cf177ec50b1f501606522bc46db027/sampleCalendar/Images.xcassets/AppIcon.appiconset/40@2x.png -------------------------------------------------------------------------------- /sampleCalendar/Images.xcassets/AppIcon.appiconset/40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jubinjacob19/CustomCalendar/0733809f51cf177ec50b1f501606522bc46db027/sampleCalendar/Images.xcassets/AppIcon.appiconset/40@3x.png -------------------------------------------------------------------------------- /sampleCalendar/Images.xcassets/AppIcon.appiconset/60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jubinjacob19/CustomCalendar/0733809f51cf177ec50b1f501606522bc46db027/sampleCalendar/Images.xcassets/AppIcon.appiconset/60@2x.png -------------------------------------------------------------------------------- /sampleCalendar/Images.xcassets/AppIcon.appiconset/60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jubinjacob19/CustomCalendar/0733809f51cf177ec50b1f501606522bc46db027/sampleCalendar/Images.xcassets/AppIcon.appiconset/60@3x.png -------------------------------------------------------------------------------- /sampleCalendar/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "29@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "29@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "40x40", 17 | "idiom" : "iphone", 18 | "filename" : "40@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "40@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "60x60", 29 | "idiom" : "iphone", 30 | "filename" : "60@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "60@3x.png", 37 | "scale" : "3x" 38 | } 39 | ], 40 | "info" : { 41 | "version" : 1, 42 | "author" : "xcode" 43 | } 44 | } -------------------------------------------------------------------------------- /sampleCalendar/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /sampleCalendar/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /sampleCalendar/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /sampleCalendar/main.m: -------------------------------------------------------------------------------- 1 | 2 | #import 3 | 4 | #import "CalendarAppDelegate.h" 5 | 6 | int main(int argc, char * argv[]) 7 | { 8 | @autoreleasepool { 9 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CalendarAppDelegate class])); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sampleCalendar/sampleCalendar-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.app.calendar 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /sampleCalendar/sampleCalendar-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /sampleCalendarTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /sampleCalendarTests/sampleCalendarTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.app.calendar 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /sampleCalendarTests/sampleCalendarTests.m: -------------------------------------------------------------------------------- 1 | 2 | 3 | #import 4 | 5 | @interface sampleCalendarTests : XCTestCase 6 | 7 | @end 8 | 9 | @implementation sampleCalendarTests 10 | 11 | - (void)setUp 12 | { 13 | [super setUp]; 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | - (void)tearDown 18 | { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | [super tearDown]; 21 | } 22 | 23 | - (void)testExample 24 | { 25 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 26 | } 27 | 28 | @end 29 | --------------------------------------------------------------------------------