You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
712 lines
29 KiB
712 lines
29 KiB
// |
|
// 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 <QuartzCore/QuartzCore.h> |
|
#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<numBlocks; |
|
|
|
//Old month |
|
float oldSize = self.calendarHeight; |
|
UIImage *imageCurrentMonth = [self drawCurrentState]; |
|
|
|
//New month |
|
self.currentMonth = [currentMonth offsetMonth:1]; |
|
if ([delegate respondsToSelector:@selector(calendarView:switchedToMonth:targetHeight: animated:)]) [delegate calendarView:self switchedToMonth:[currentMonth month] targetHeight:self.calendarHeight animated:YES]; |
|
prepAnimationNextMonth=NO; |
|
[self setNeedsDisplay]; |
|
|
|
UIImage *imageNextMonth = [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]; |
|
|
|
//Animate |
|
self.animationView_A = [[UIImageView alloc] initWithImage:imageCurrentMonth]; |
|
self.animationView_B = [[UIImageView alloc] initWithImage:imageNextMonth]; |
|
[animationHolder addSubview:animationView_A]; |
|
[animationHolder addSubview:animationView_B]; |
|
|
|
if (hasNextMonthDays) { |
|
animationView_B.frameY = animationView_A.frameY + animationView_A.frameHeight - (kVRGCalendarViewDayHeight+3); |
|
} else { |
|
animationView_B.frameY = animationView_A.frameY + animationView_A.frameHeight -3; |
|
} |
|
|
|
//Animation |
|
__block VRGCalendarView *blockSafeSelf = self; |
|
[UIView animateWithDuration:.35 |
|
animations:^{ |
|
[self updateSize]; |
|
//blockSafeSelf.frameHeight = 100; |
|
if (hasNextMonthDays) { |
|
animationView_A.frameY = -animationView_A.frameHeight + kVRGCalendarViewDayHeight+3; |
|
} else { |
|
animationView_A.frameY = -animationView_A.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 - Next & Previous |
|
-(void)showNextMonth { |
|
// dateLimit setting ------SL |
|
if([self.currentMonth year] <= [[NSDate date] year]){ |
|
NSLog(@"YES"); |
|
} |
|
NSLog(@"[self.currentMonth month] ===== %d",[self.currentMonth month]); |
|
NSLog(@"[[NSDate date] month] ====== %d",[[NSDate date] month]); |
|
NSLog(@"_limitMonth ===== %ld",(long)_limitMonth); |
|
|
|
if ([self.currentMonth month] >= [[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, 60, 40); |
|
CGRect rectArrowRight = CGRectMake(self.frame.size.width-60, 0, 60, 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年%@",year,[monthArr objectAtIndex:month-1]]; |
|
}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, KKWhiteColorColor.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, KKWhiteColorColor.CGColor); |
|
CGContextFillPath(context); |
|
|
|
//Arrows |
|
int arrowSize = 14; |
|
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, mainColor.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, mainColor.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, |
|
RGB(163, 162, 160).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), 55, 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, KKWhiteColorColor.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, RGB(240, 240, 240).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,mainColor.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<numBlocks; i++) { |
|
int targetDate = i; |
|
int targetColumn = i%7; |
|
int targetRow = i/7; |
|
int targetX = targetColumn * (kVRGCalendarViewDayWidth+2); |
|
int targetY = kVRGCalendarViewTopBarHeight + targetRow * (kVRGCalendarViewDayHeight+2); |
|
|
|
// BOOL isCurrentMonth = NO; |
|
if (i<firstWeekDay) { //previous month |
|
targetDate = (prevMonthNumDays-firstWeekDay)+(i+1); |
|
NSString *hex = (isSelectedDatePreviousMonth) ? @"0x383838" : @"aaaaaa"; |
|
CGContextSetFillColorWithColor(context, |
|
[UIColor colorWithHexString:hex].CGColor); |
|
} else if (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,mainColor.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, targetY+20, 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 = KKGrey102; |
|
labelCurrentMonth.backgroundColor = KKWhiteColorColor; |
|
labelCurrentMonth.font = FontBold_(16); |
|
// labelCurrentMonth.textColor = [UIColor colorWithHexString:@"0x383838"]; |
|
labelCurrentMonth.textColor = KKBlack20; |
|
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
|
|
|