最近在做項目,遇到了日歷需求,于是左思右想,決定自己寫一下。本文在做日歷有些取巧,算不上正統的思路,希望能為你打開一片新的天地。
需求
正如你所看,需要做出公歷和農歷,同時需要設置周六日默認橘紅色,點擊某個日期,出現橘色背景同時文字發生顏色變化,然后可以切換日期,這里只能逐月切換,有興趣的朋友可以修改一下,很容易修改。
1> 對于日歷,這里只需要知道每個月的第一天是周幾即可,后面順序排下來,然后知道這個月有幾天,有了這兩個數據就能算出這個月的公歷。
// 獲取該月的天數
- (NSInteger)getNumberOfDaysInMonthWithMonth:(NSInteger)number withYear:(NSInteger)year
{
NSDate * currentDate = [self getPriousorLaterDateFromDate:self.date withMonth:number withYear:year];
// 這個日期可以你自己給定
NSRange range = [self.calendar rangeOfUnit:NSCalendarUnitDay
inUnit: NSCalendarUnitMonth
forDate:currentDate];
return range.length;
}
/**
* 獲取當月中所有天數是周幾
*/
- (NSArray*) getAllDayWeeksWithCalendarWithMonth:(NSInteger)number withYear:(NSInteger)year
{
//一個月的總天數
NSUInteger dayCount = [self getNumberOfDaysInMonthWithMonth:number withYear:year];
NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM"];
NSString * str = [formatter stringFromDate:[self getPriousorLaterDateFromDate:self.date withMonth:number withYear:year]];
[formatter setDateFormat:@"yyyy-MM-dd"];
NSMutableArray * allDayWeeksArray = [[NSMutableArray alloc] init];
for (NSInteger i = 1; i <= dayCount; i++) {
NSString * sr = [NSString stringWithFormat:@"%@-%ld",str,i];
NSDate *suDate = [formatter dateFromString:sr];
[allDayWeeksArray addObject:[self getweekDayWithDate:suDate]];
}
return allDayWeeksArray;
}
/**
* 獲得某天的數據
*
* 獲取指定的日期是星期幾
*/
- (id) getweekDayWithDate:(NSDate *) date
{
NSDateComponents *comps = [self.calendar components:NSCalendarUnitWeekday fromDate:date];
// 1 是周日,2是周一 3.以此類推
return @([comps weekday]);
}
在這里,我封裝了一個函數,方便獲取每個月的date數據
//獲取指定某個月的date數據
- (NSDate *)getPriousorLaterDateFromDate:(NSDate *)date withMonth:(NSInteger)month withYear:(NSInteger)year
{
NSDateComponents *comp = [[NSDateComponents alloc]init];
[comp setMonth:month];
[comp setYear:year];
NSDate *currentDate = [self.calendar dateFromComponents:comp];
return currentDate;
}
到此,基本上公歷數據就可以了,然后通過UICollectionViewController布局日歷即可。
2>說到布局,這里就在于我取巧的部分,我并沒有獲取到正統的公歷,我只獲取了每個月的第一天和天數。比如,2017年9月的第一天是周五,那么此時返回item的個數就應該是5+這個月的天數,日歷都是從周日開始算的,然后算出35個單元格,第一個格是在indexPath.item = 5,然后這一天是周五,item = 5,是1號。
默認初始每個格就是item的值,那么第一個格為0,然后依次排到最后一個格是34,日歷上沒有0,那么這里需要得到item + 1這個數,35個格,從1排到35。現在要將周五上是item + 1,是6,這個數變成1,即減去5,也即是這個月前面從周日到這一天沒有日期的天數,9月份有5天,然后得出,9月1號在周五,然后前面的值均小于1,然后做一步判斷將item里面的值置為""即可。其余的月份都是如此,你可以自己試試別的月份。
3>農歷部分在網上找到的,難度比較大,直接拿來用的。
先前直接計算出來的日期,這時候得到年月日,拼接起來算出公歷日期。
// 字符串轉date
-(NSDate* )theTargetStringConversionDate:(NSString *)str
{
//設置轉換格式
NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
[formatter setDateFormat:@"yyyy-MM-dd"];
//NSString轉NSDate
NSDate *date=[formatter dateFromString:str];
return date;
}
然后,通過公歷日期,得出農歷日期,這部分難度稍大,有興趣的小伙伴可以自行研究一下。
至此,核心部分講述完畢,有需要的小伙伴可以下載demo研究。
Demo地址:https://github.com/mayuwen/Calendar