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.
713 lines
29 KiB
713 lines
29 KiB
1 year ago
|
//
|
||
|
// 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
|