// // VRGCalendarView.m // Vurig // // Created by in 't Veen Tjeerd on 5/8/12. // Copyright (c) 2012 Vurig Media. All rights reserved. // #import "VRGCalendarView.h" #import #import "NSDate+convenience.h" #import "NSMutableArray+convenience.h" #import "UIView+convenience.h" @interface VRGCalendarView() @property (nonatomic) NSInteger limitMonth; @end @implementation VRGCalendarView @synthesize currentMonth,delegate,labelCurrentMonth, animationView_A,animationView_B; @synthesize markedDates,markedColors,calendarHeight,selectedDate; #pragma mark - Select Date -(void)selectDate:(int)date { NSArray *languages = [NSLocale preferredLanguages]; NSString *currentLanguage = [languages objectAtIndex:0]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; gregorian.locale = [[[NSLocale alloc]initWithLocaleIdentifier:currentLanguage]autorelease]; NSDateComponents *comps = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:self.currentMonth]; [comps setDay:date]; self.selectedDate = [gregorian dateFromComponents:comps]; int selectedDateYear = [selectedDate year]; int selectedDateMonth = [selectedDate month]; int currentMonthYear = [currentMonth year]; int currentMonthMonth = [currentMonth month]; if (selectedDateYear < currentMonthYear) { [self showPreviousMonth]; } else if (selectedDateYear > currentMonthYear) { [self showNextMonth]; } else if (selectedDateMonth < currentMonthMonth) { [self showPreviousMonth]; } else if (selectedDateMonth > currentMonthMonth) { [self showNextMonth]; } else { [self setNeedsDisplay]; } if ([delegate respondsToSelector:@selector(calendarView:dateSelected:)]) [delegate calendarView:self dateSelected:self.selectedDate]; } #pragma mark - Mark Dates //NSArray can either contain NSDate objects or NSNumber objects with an int of the day. -(void)markDates:(NSArray *)dates { self.markedDates = dates; NSMutableArray *colors = [[NSMutableArray alloc] init]; for (int i = 0; i<[dates count]; i++) { [colors addObject:[UIColor colorWithHexString:@"0x383838"]]; } self.markedColors = [NSArray arrayWithArray:colors]; [colors release]; [self setNeedsDisplay]; } //NSArray can either contain NSDate objects or NSNumber objects with an int of the day. -(void)markDates:(NSArray *)dates withColors:(NSArray *)colors { self.markedDates = dates; self.markedColors = colors; [self setNeedsDisplay]; } #pragma mark - Set date to now -(void)reset { NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; NSDateComponents *components = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate: [NSDate date]]; self.currentMonth = [gregorian dateFromComponents:components]; //clean month NSTimeZone *zone = [NSTimeZone systemTimeZone]; NSInteger interval = [zone secondsFromGMTForDate:[NSDate date]]; self.currentMonth = [self.currentMonth dateByAddingTimeInterval:interval]; [self updateSize]; [self setNeedsDisplay]; [delegate calendarView:self switchedToMonth:[currentMonth month] targetHeight:self.calendarHeight animated:NO]; } - (void)nextMonth { if (isAnimating) return; self.markedDates=nil; isAnimating=YES; prepAnimationNextMonth=YES; [self setNeedsDisplay]; int lastBlock = [currentMonth firstWeekDayInMonth]+[currentMonth numDaysInMonth]-1; int numBlocks = [self numRows]*7; BOOL hasNextMonthDays = lastBlock= [[NSDate date] month] && _limitMonth) { if ([self.currentMonth year] < [[NSDate date] year]) { [self nextMonth]; } } else { [self nextMonth]; } } -(void)showPreviousMonth { // dateLimit setting ------SL if ([self.currentMonth month] <= ([[NSDate date] month]-_limitMonth) && _limitMonth) { return; } // dateLimit setting ------SL if (isAnimating) return; isAnimating=YES; self.markedDates=nil; //Prepare current screen prepAnimationPreviousMonth = YES; [self setNeedsDisplay]; BOOL hasPreviousDays = [currentMonth firstWeekDayInMonth]>1; float oldSize = self.calendarHeight; UIImage *imageCurrentMonth = [self drawCurrentState]; //Prepare next screen self.currentMonth = [currentMonth offsetMonth:-1]; if ([delegate respondsToSelector:@selector(calendarView:switchedToMonth:targetHeight:animated:)]) [delegate calendarView:self switchedToMonth:[currentMonth month] targetHeight:self.calendarHeight animated:YES]; prepAnimationPreviousMonth=NO; [self setNeedsDisplay]; UIImage *imagePreviousMonth = [self drawCurrentState]; float targetSize = fmaxf(oldSize, self.calendarHeight); UIView *animationHolder = [[UIView alloc] initWithFrame:CGRectMake(0, kVRGCalendarViewTopBarHeight, kVRGCalendarViewWidth, targetSize-kVRGCalendarViewTopBarHeight)]; [animationHolder setClipsToBounds:YES]; [self addSubview:animationHolder]; [animationHolder release]; self.animationView_A = [[UIImageView alloc] initWithImage:imageCurrentMonth]; self.animationView_B = [[UIImageView alloc] initWithImage:imagePreviousMonth]; [animationHolder addSubview:animationView_A]; [animationHolder addSubview:animationView_B]; if (hasPreviousDays) { animationView_B.frameY = animationView_A.frameY - (animationView_B.frameHeight-kVRGCalendarViewDayHeight) + 3; } else { animationView_B.frameY = animationView_A.frameY - animationView_B.frameHeight + 3; } __block VRGCalendarView *blockSafeSelf = self; [UIView animateWithDuration:.35 animations:^{ [self updateSize]; if (hasPreviousDays) { animationView_A.frameY = animationView_B.frameHeight-(kVRGCalendarViewDayHeight+3); } else { animationView_A.frameY = animationView_B.frameHeight-3; } animationView_B.frameY = 0; } completion:^(BOOL finished) { [animationView_A removeFromSuperview]; [animationView_B removeFromSuperview]; blockSafeSelf.animationView_A=nil; blockSafeSelf.animationView_B=nil; isAnimating=NO; [animationHolder removeFromSuperview]; } ]; } #pragma mark - update size & row count -(void)updateSize { self.frameHeight = self.calendarHeight; [self setNeedsDisplay]; } -(float)calendarHeight { return kVRGCalendarViewTopBarHeight + [self numRows]*(kVRGCalendarViewDayHeight+2)+1; } -(int)numRows { float lastBlock = [self.currentMonth numDaysInMonth]+([self.currentMonth firstWeekDayInMonth]-1); return ceilf(lastBlock/7); } #pragma mark - Touches -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint touchPoint = [touch locationInView:self]; self.selectedDate=nil; //Touch a specific day if (touchPoint.y > kVRGCalendarViewTopBarHeight) { float xLocation = touchPoint.x; float yLocation = touchPoint.y-kVRGCalendarViewTopBarHeight; int column = floorf(xLocation/(kVRGCalendarViewDayWidth+2)); int row = floorf(yLocation/(kVRGCalendarViewDayHeight+2)); int blockNr = (column+1)+row*7; int firstWeekDay = [self.currentMonth firstWeekDayInMonth]-1; //-1 because weekdays begin at 1, not 0 int date = blockNr-firstWeekDay; // dateLimit setting ------SL if (_limitMonth && [self.currentMonth month] == [[NSDate date] month] && date > [[NSDate date] day]) { return; } NSDate *limitDate = [NSDate dateWithTimeInterval:-(_limitDay*24*3600) sinceDate:[NSDate date]]; if (_limitMonth && [self.currentMonth month] == ([[NSDate date] month]-_limitMonth) && [limitDate day] > date-1) { return; } // dateLimit setting ------SL [self selectDate:date]; return; } self.markedDates=nil; self.markedColors=nil; CGRect rectArrowLeft = CGRectMake(0, 0, 50, 40); CGRect rectArrowRight = CGRectMake(self.frame.size.width-50, 0, 50, 40); //Touch either arrows or month in middle if (CGRectContainsPoint(rectArrowLeft, touchPoint)) { [self showPreviousMonth]; } else if (CGRectContainsPoint(rectArrowRight, touchPoint)) { [self showNextMonth]; } else if (CGRectContainsPoint(self.labelCurrentMonth.frame, touchPoint)) { //Detect touch in current month int currentMonthIndex = [self.currentMonth month]; int todayMonth = [[NSDate date] month]; [self reset]; if ((todayMonth!=currentMonthIndex) && [delegate respondsToSelector:@selector(calendarView:switchedToMonth:targetHeight:animated:)]) [delegate calendarView:self switchedToMonth:[currentMonth month] targetHeight:self.calendarHeight animated:NO]; } } #pragma mark - Drawing - (void)drawRect:(CGRect)rect { int firstWeekDay = [self.currentMonth firstWeekDayInMonth] - 1; //-1 because weekdays begin at 1, not 0 // NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; NSArray *languages = [NSLocale preferredLanguages]; NSString *currentLanguage = [languages objectAtIndex:0]; NSArray *monthArr; if ([currentLanguage rangeOfString:@"Hans"].length) { monthArr = @[@"1月",@"2月",@"3月",@"4月",@"5月",@"6月",@"7月",@"8月",@"9月",@"10月",@"11月",@"12月"]; }else if([currentLanguage isEqualToString:@"it"]){ monthArr = @[@"1 mese",@"2 mese",@"3 mese",@"4 mese",@"5 mese",@"6 mese",@"7 mese",@"8 mese",@"9 mese",@"10 mese",@"11 mese",@"12 mese"]; }else if ([currentLanguage isEqualToString:@"de"]){ monthArr = @[@"1. Monat",@"2. Monat",@"3. Monat",@". Monat",@"5 mese",@"6. Monat",@"7. Monat",@"8. Monat",@"9. Monat",@"10. Monat",@"11. Monat",@"12. Monat"]; }else if([currentLanguage isEqualToString:@"fa"]){ monthArr = @[@"1 mois",@"2 mois",@"3 mois",@"4 mois",@"5 mois",@"6 mois",@"7 mois",@"8 mois",@"9 mois",@"10 mois",@"11 mois",@"12 mois"]; }else if ([currentLanguage isEqualToString:@"zh-hant"]){ monthArr = @[@"1月",@"2月",@"3月",@"4月",@"5月",@"6月",@"7月",@"8月",@"9月",@"10月",@"11月",@"12月"]; }else if ([currentLanguage isEqualToString:@"ru"]){ monthArr = @[@"Январь",@"Февраль",@"Март",@"Апрель",@"Май",@"Июнь",@"Июль",@"Август",@"Сентябрь",@"Октябрь",@"Ноябрь",@"Декабрь"]; }else{ monthArr = @[@"Jan",@"Feb",@"Mar",@"Apr",@"May",@"June",@"July",@"Aug",@"Sept",@"Oct",@"Nov",@"Dec"]; } NSCalendar *caledar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; NSUInteger units = NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay; NSDateComponents *dateComponents = [caledar components:units fromDate:self.currentMonth]; NSInteger year = [dateComponents year]; NSInteger month = [dateComponents month]; if (month >0 && month <= 12) { labelCurrentMonth.text = [NSString stringWithFormat:@"%@ %ld",[monthArr objectAtIndex:month-1],year]; }else{ NSDateFormatter *formatter = [[[NSDateFormatter alloc]init]autorelease]; formatter.locale = [[[NSLocale alloc]initWithLocaleIdentifier:currentLanguage]autorelease]; [formatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]]; [formatter setDateFormat:@"MMMM yyyy"]; labelCurrentMonth.text = [formatter stringFromDate:self.currentMonth]; } // [labelCurrentMonth sizeToFit]; labelCurrentMonth.frameX = roundf(self.frame.size.width/2 - labelCurrentMonth.frameWidth/2); labelCurrentMonth.frameY = 0; [currentMonth firstWeekDayInMonth]; CGContextClearRect(UIGraphicsGetCurrentContext(),rect); CGContextRef context = UIGraphicsGetCurrentContext(); context = UIGraphicsGetCurrentContext(); CGRect rectangle1 = CGRectMake(0,0,self.frame.size.width,labelCurrentMonth.frame.size.height); CGContextAddRect(context, rectangle1); CGContextSetFillColorWithColor(context , mainColor.CGColor); CGContextFillPath(context); CGContextSaveGState(context); CGRect rectangle = CGRectMake(0,labelCurrentMonth.frame.size.height,self.frame.size.width,kVRGCalendarViewTopBarHeight-labelCurrentMonth.frame.size.height); CGContextAddRect(context, rectangle); CGContextSetFillColorWithColor(context, [UIColor lightGrayColor].CGColor); CGContextFillPath(context); //Arrows int arrowSize = 12; int xmargin = 5; int ymargin = 14; //Arrow Left CGContextBeginPath(context); CGContextMoveToPoint(context, xmargin+arrowSize/1.5, ymargin); CGContextAddLineToPoint(context,xmargin+arrowSize/1.5,ymargin+arrowSize); CGContextAddLineToPoint(context,xmargin,ymargin+arrowSize/2); CGContextAddLineToPoint(context,xmargin+arrowSize/1.5, ymargin); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextFillPath(context); //Arrow right CGContextBeginPath(context); CGContextMoveToPoint(context, self.frame.size.width-(xmargin+arrowSize/1.5), ymargin); CGContextAddLineToPoint(context,self.frame.size.width-xmargin,ymargin+arrowSize/2); CGContextAddLineToPoint(context,self.frame.size.width-(xmargin+arrowSize/1.5),ymargin+arrowSize); CGContextAddLineToPoint(context,self.frame.size.width-(xmargin+arrowSize/1.5), ymargin); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); CGContextFillPath(context); //Weekdays NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]]; dateFormatter.dateFormat=@"EEE"; dateFormatter.locale = [[[NSLocale alloc]initWithLocaleIdentifier:currentLanguage]autorelease]; //always assume gregorian with monday first NSMutableArray *weekdays = [[NSMutableArray alloc] initWithArray:[dateFormatter shortWeekdaySymbols]]; [weekdays moveObjectFromIndex:0 toIndex:6]; CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0x383838"].CGColor); for (int i =0; i<[weekdays count]; i++) { NSString *weekdayValue = (NSString *)[weekdays objectAtIndex:i]; UIFont *font = [UIFont fontWithName:@"HelveticaNeue" size:12]; [weekdayValue drawInRect:CGRectMake(i*(kVRGCalendarViewDayWidth+2), 40, kVRGCalendarViewDayWidth+2, 20) withFont:font lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter]; } int numRows = [self numRows]; CGContextSetAllowsAntialiasing(context, NO); //Grid background float gridHeight = numRows*(kVRGCalendarViewDayHeight+2)+1; CGRect rectangleGrid = CGRectMake(0,kVRGCalendarViewTopBarHeight,self.frame.size.width,gridHeight); CGContextAddRect(context, rectangleGrid); CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0xf3f3f3"].CGColor); //CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0xff0000"].CGColor); CGContextFillPath(context); //Grid white lines // CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor); // CGContextBeginPath(context); // CGContextMoveToPoint(context, 0, kVRGCalendarViewTopBarHeight+1); // CGContextAddLineToPoint(context, kVRGCalendarViewWidth, kVRGCalendarViewTopBarHeight+1); // for (int i = 1; i<7; i++) { // CGContextMoveToPoint(context, i*(kVRGCalendarViewDayWidth+1)+i*1-1, kVRGCalendarViewTopBarHeight); // CGContextAddLineToPoint(context, i*(kVRGCalendarViewDayWidth+1)+i*1-1, kVRGCalendarViewTopBarHeight+gridHeight); // // if (i>numRows-1) continue; // //rows // CGContextMoveToPoint(context, 0, kVRGCalendarViewTopBarHeight+i*(kVRGCalendarViewDayHeight+1)+i*1+1); // CGContextAddLineToPoint(context, kVRGCalendarViewWidth, kVRGCalendarViewTopBarHeight+i*(kVRGCalendarViewDayHeight+1)+i*1+1); // } // // CGContextStrokePath(context); // //Grid dark lines CGContextSetStrokeColorWithColor(context, [UIColor colorWithHexString:@"0xcfd4d8"].CGColor); CGContextBeginPath(context); CGContextMoveToPoint(context, 0, kVRGCalendarViewTopBarHeight); CGContextAddLineToPoint(context, kVRGCalendarViewWidth, kVRGCalendarViewTopBarHeight); for (int i = 1; i<7; i++) { //columns CGContextMoveToPoint(context, i*(kVRGCalendarViewDayWidth+1)+i*1, kVRGCalendarViewTopBarHeight); CGContextAddLineToPoint(context, i*(kVRGCalendarViewDayWidth+1)+i*1, kVRGCalendarViewTopBarHeight+gridHeight); if (i>numRows-1) continue; //rows CGContextMoveToPoint(context, 0, kVRGCalendarViewTopBarHeight+i*(kVRGCalendarViewDayHeight+1)+i*1); CGContextAddLineToPoint(context, kVRGCalendarViewWidth, kVRGCalendarViewTopBarHeight+i*(kVRGCalendarViewDayHeight+1)+i*1); } CGContextMoveToPoint(context, 0, gridHeight+kVRGCalendarViewTopBarHeight); CGContextAddLineToPoint(context, kVRGCalendarViewWidth, gridHeight+kVRGCalendarViewTopBarHeight); CGContextStrokePath(context); CGContextSetAllowsAntialiasing(context, YES); //Draw days CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0x383838"].CGColor); int numBlocks = numRows*7; NSDate *previousMonth = [self.currentMonth offsetMonth:-1]; int currentMonthNumDays = [currentMonth numDaysInMonth]; int prevMonthNumDays = [previousMonth numDaysInMonth]; int selectedDateBlock = ([selectedDate day]-1)+firstWeekDay; //prepAnimationPreviousMonth nog wat mee doen //prev next month BOOL isSelectedDatePreviousMonth = prepAnimationPreviousMonth; BOOL isSelectedDateNextMonth = prepAnimationNextMonth; if (self.selectedDate!=nil) { isSelectedDatePreviousMonth = ([selectedDate year]==[currentMonth year] && [selectedDate month]<[currentMonth month]) || [selectedDate year] < [currentMonth year]; if (!isSelectedDatePreviousMonth) { isSelectedDateNextMonth = ([selectedDate year]==[currentMonth year] && [selectedDate month]>[currentMonth month]) || [selectedDate year] > [currentMonth year]; } } if (isSelectedDatePreviousMonth) { int lastPositionPreviousMonth = firstWeekDay-1; selectedDateBlock=lastPositionPreviousMonth-([selectedDate numDaysInMonth]-[selectedDate day]); } else if (isSelectedDateNextMonth) { selectedDateBlock = [currentMonth numDaysInMonth] + (firstWeekDay-1) + [selectedDate day]; } NSDate *todayDate = [NSDate date]; int todayBlock = -1; // NSLog(@"currentMonth month = %i day = %i, todaydate day = %i",[currentMonth month],[currentMonth day],[todayDate month]); if ([todayDate month] == [currentMonth month] && [todayDate year] == [currentMonth year]) { todayBlock = [todayDate day] + firstWeekDay - 1; } for (int i=0; i=(firstWeekDay+currentMonthNumDays)) { //next month targetDate = (i+1) - (firstWeekDay+currentMonthNumDays); NSString *hex = (isSelectedDateNextMonth) ? @"0x383838" : @"0xaaaaaa"; CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:hex].CGColor); } else { //current month targetDate = (i-firstWeekDay)+1; NSString *hex = (isSelectedDatePreviousMonth || isSelectedDateNextMonth) ? @"0xaaaaaa" : @"0x383838"; CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:hex].CGColor); } NSString *date = [NSString stringWithFormat:@"%i",targetDate]; //draw selected date if (selectedDate && i==selectedDateBlock) { CGRect rectangleGrid = CGRectMake(targetX,targetY,kVRGCalendarViewDayWidth+2,kVRGCalendarViewDayHeight+2); CGContextAddRect(context, rectangleGrid); CGContextSetFillColorWithColor(context, mainColor.CGColor); CGContextFillPath(context); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); } else { if (todayBlock==i) { CGRect rectangleGrid = CGRectMake(targetX,targetY,kVRGCalendarViewDayWidth+2,kVRGCalendarViewDayHeight+2); CGContextAddRect(context, rectangleGrid); CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0x383838"].CGColor); CGContextFillPath(context); CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); } // dateLimit setting ------SL if (_limitMonth && [self.currentMonth month] == [[NSDate date] month] && todayBlock < i) { CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0xaaaaaa"].CGColor); } NSDate *limitDate = [NSDate dateWithTimeInterval:-(_limitDay*24*3600) sinceDate:[NSDate date]]; if (_limitMonth && [self.currentMonth month] == ([[NSDate date] month]-_limitMonth) && [limitDate day] > (i-firstWeekDay)) { CGContextSetFillColorWithColor(context, [UIColor colorWithHexString:@"0xaaaaaa"].CGColor); } // dateLimit setting ------SL } [date drawInRect:CGRectMake(targetX+2, targetY+10, kVRGCalendarViewDayWidth, kVRGCalendarViewDayHeight) withFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:17] lineBreakMode:NSLineBreakByClipping alignment:NSTextAlignmentCenter]; } // CGContextClosePath(context); //Draw markings if (!self.markedDates || isSelectedDatePreviousMonth || isSelectedDateNextMonth) return; for (int i = 0; i<[self.markedDates count]; i++) { id markedDateObj = [self.markedDates objectAtIndex:i]; int targetDate; if ([markedDateObj isKindOfClass:[NSNumber class]]) { targetDate = [(NSNumber *)markedDateObj intValue]; } else if ([markedDateObj isKindOfClass:[NSDate class]]) { NSDate *date = (NSDate *)markedDateObj; targetDate = [date day]; } else { continue; } int targetBlock = firstWeekDay + (targetDate-1); int targetColumn = targetBlock%7; int targetRow = targetBlock/7; int targetX = targetColumn * (kVRGCalendarViewDayWidth+2) + 7; int targetY = kVRGCalendarViewTopBarHeight + targetRow * (kVRGCalendarViewDayHeight+2) + 38; CGRect rectangle = CGRectMake(targetX,targetY,32,2); CGContextAddRect(context, rectangle); UIColor *color; if (selectedDate && selectedDateBlock==targetBlock) { color = [UIColor whiteColor]; } else if (todayBlock==targetBlock) { color = [UIColor whiteColor]; } else { color = (UIColor *)[markedColors objectAtIndex:i]; } CGContextSetFillColorWithColor(context, color.CGColor); CGContextFillPath(context); } } #pragma mark - Draw image for animation -(UIImage *)drawCurrentState { float targetHeight = kVRGCalendarViewTopBarHeight + [self numRows]*(kVRGCalendarViewDayHeight+2)+1; UIGraphicsBeginImageContext(CGSizeMake(kVRGCalendarViewWidth, targetHeight-kVRGCalendarViewTopBarHeight)); CGContextRef c = UIGraphicsGetCurrentContext(); CGContextTranslateCTM(c, 0, -kVRGCalendarViewTopBarHeight); // <-- shift everything up by 40px when drawing. [self.layer renderInContext:c]; UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return viewImage; } #pragma mark - Init -(id)init { self = [super initWithFrame:CGRectMake(20, 0, kVRGCalendarViewWidth, 0)]; if (self) { self.contentMode = UIViewContentModeTop; self.clipsToBounds = YES; isAnimating = NO; self.labelCurrentMonth = [[UILabel alloc] initWithFrame:CGRectMake(34, 0, kVRGCalendarViewWidth-68, 40)]; [self addSubview:labelCurrentMonth]; labelCurrentMonth.backgroundColor = mainColor; labelCurrentMonth.font = [UIFont fontWithName:@"HelveticaNeue" size:17]; // labelCurrentMonth.textColor = [UIColor colorWithHexString:@"0x383838"]; labelCurrentMonth.textColor = [UIColor whiteColor]; labelCurrentMonth.textAlignment = NSTextAlignmentCenter; [self performSelector:@selector(reset) withObject:nil afterDelay:0.1]; //so delegate can be set after init and still get called on init } return self; } // dateLimit setting ------SL - (void)setLimitDay:(NSInteger)limitDay { _limitDay = limitDay; _limitMonth = _limitDay ? ceil(_limitDay / 31.0) : 0; } // dateLimit setting ------SL - (void)dismiss{ } -(void)dealloc { self.delegate=nil; self.currentMonth=nil; self.labelCurrentMonth=nil; self.markedDates=nil; self.markedColors=nil; [super dealloc]; } @end