YFCalendar----最新版自写日历
2016-05-24 13:45
381 查看
简介
最新版的自己写的日历,有农历和阳历。之前写的只是为了实现功能,没有注重代码的简洁性,这次我把代码进行了一定的分类封装。水平不够,多谢指教。
有需求的可以看看~~~~~,有能力的来个星星谢谢哈
Demo传送门
框架布局
最重要的就是tools和yfcollectionview的代码:
工具类包括所有的日期计算方法:
#import <Foundation/Foundation.h> #import "SSLunarDate.h" @interface NSObject (CalenderSet) - (NSInteger)currentYear:(NSDate *)date;//获得当前的年份 - (NSInteger)currentMonth:(NSDate *)date;//获得当前的月份 - (NSInteger)currentDay:(NSDate *)date;//获得当前是哪一天 - (NSInteger)currentMonthOfDay:(NSDate *)date;//获得本月有多少天 - (NSInteger)preInMonth:(NSDate *)date;//获得上个月月份 - (NSInteger)nextMonth:(NSDate *)date;//获得下个月月份 - (NSInteger)preInMonthDay:(NSDate *)date;//获得上个月有多少天 - (NSInteger)currentFirstDay:(NSDate *)date;//获得这个月份第一天是在星期几 - (NSMutableArray *)currentMonthArray:(NSDate *)date;//获得这个月排布数组 - (void)changeCurrentMonth:(NSDate *)date andIndex:(int)index resultData:(void(^)(NSDate *nowDate,NSString *showMonth))block;//获得上个月或者下个月的对应的nsdate和字符串 - (SSLunarDate *)lunarDaysString:(NSDate *)date int:(int)nowIndex;//获取对应的农历 @end
#import "NSObject+CalenderSet.h" @implementation NSObject (CalenderSet) /** * 获取当前月的年份 */ - (NSInteger)currentYear:(NSDate *)date{ NSDateComponents *componentsYear = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date]; return [componentsYear year]; } /** * 获取当前月的月份 */ - (NSInteger)currentMonth:(NSDate *)date{ NSDateComponents *componentsMonth = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date]; return [componentsMonth month]; } /** * 获取当前是哪一天 * * @param date <#date description#> * * @return <#return value description#> */ - (NSInteger)currentDay:(NSDate *)date{ NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date]; return [components day]; } /** * 本月有几天 * * @param date <#date description#> * * @return <#return value description#> */ - (NSInteger)currentMonthOfDay:(NSDate *)date{ NSRange totaldaysInMonth = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date]; return totaldaysInMonth.length; } /** * 本月的上一个月是第几个月 * * @param date <#date description#> * * @return <#return value description#> */ - (NSInteger)preInMonth:(NSDate *)date{ //获取这个月月份 NSInteger currentMonth = [self currentMonth:date]; NSInteger preMonth; //判断上一个月是哪个月份 if (currentMonth == 1) { preMonth = 12; }else{ preMonth = currentMonth - 1; } return preMonth; } /** * 本月的下一个月是第几个月 * * @param date <#date description#> * * @return <#return value description#> */ - (NSInteger)nextMonth:(NSDate *)date{ //获取这个月月份 NSInteger currentMonth = [self currentMonth:date]; NSInteger preMonth; //判断下一个月是哪个月份 if (currentMonth == 12) { preMonth = 1; }else{ preMonth = currentMonth + 1; } return preMonth; } /** * 上一个月是有多少天数 * * @param date <#date description#> * * @return <#return value description#> */ - (NSInteger)preInMonthDay:(NSDate *)date{ NSInteger currnetYear = [self currentYear:date]; NSInteger preMonth = [self preInMonth:date]; //判断年份是不是闰年 if (preMonth == 1 || preMonth == 3 || preMonth == 5 || preMonth == 7 || preMonth == 8 || preMonth == 10 || preMonth == 12) { return 31; }else if(preMonth == 2){ //如果是闰年并且这个月份正好是二月份 if(((currnetYear % 4 == 0) && (currnetYear % 100 == 0)) || (currnetYear % 400 == 0)){ return 29; }else{ return 28; } }else{ return 30; } } /** * 本月第一天是星期几 * * @param date <#date description#> * * @return <#return value description#> */ - (NSInteger)currentFirstDay:(NSDate *)date{ NSCalendar *calendar = [NSCalendar currentCalendar]; // [calendar setFirstWeekday:2];//1.mon NSDateComponents *comp = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date]; [comp setDay:1]; NSDate *firstDayOfMonthDate = [calendar dateFromComponents:comp]; NSUInteger firstWeekday = [calendar ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitWeekOfMonth forDate:firstDayOfMonthDate]; return firstWeekday - 1; } /** * 获得对应月份的天数数组 * * @param date <#date description#> * * @return <#return value description#> */ - (NSMutableArray *)currentMonthArray:(NSDate *)date{ NSMutableArray *dayArray = [NSMutableArray array]; //获取上一个月是第几个月 NSInteger preMonth = [self preInMonth:date]; //获取上一个月天数 NSInteger preDay = [self preInMonthDay:date]; //获取下一个月是第几个月 NSInteger nextMonth = [self nextMonth:date]; //当月月份 NSInteger currentMonth = [self currentMonth:date]; NSInteger day = [self currentFirstDay:date]; for (NSInteger i = 0; i < day; i++){ //存入字典 NSDictionary *preDic = @{@"month":@(preMonth),@"day":@(preDay - day + i + 1),@"status":@"pre"}; [dayArray addObject:preDic]; } NSInteger days = [self currentMonthOfDay:date]; for (NSInteger i = 1; i <= days; i++) { //存入字典 NSDictionary *currentDic = @{@"month":@(currentMonth),@"day":@(i),@"status":@"current"}; [dayArray addObject:currentDic]; } //把剩下的空间置为空 int lastCount = 1; for (NSInteger i = dayArray.count; i < 42; i ++) { //存入字典 NSDictionary *nextDic = @{@"month":@(nextMonth),@"day":@(lastCount),@"status":@"next"}; [dayArray addObject:nextDic]; lastCount ++; } return dayArray; } /** * 获得对应的nsdate和显示的年份月份 * */ - (void)changeCurrentMonth:(NSDate *)date andIndex:(int)index resultData:(void(^)(NSDate *nowDate,NSString *showMonth))block{ NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; dateComponents.month = index; NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0]; if (block) { block(newDate,[NSString stringWithFormat:@"%li年%li月",(long)[self currentYear:newDate],(long)[self currentMonth:newDate]]); } } /** * 获取对应的农历 * * @return <#return value description#> */ - (SSLunarDate *)lunarDaysString:(NSDate *)date int:(int)nowIndex{ NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; //设置天数 [dateComponents setDay:nowIndex]; NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0]; SSLunarDate *lunar = [[SSLunarDate alloc] initWithDate:newDate]; return lunar; } @end
然后是collectionview布局:
#import "YFCollectionView.h" #import "YFCell.h" #import "NSObject+CalenderSet.h" #import "SSLunarDate.h" @interface YFCollectionView()<UICollectionViewDelegate,UICollectionViewDataSource> @end @implementation YFCollectionView /** * init * */ - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout{ self = [super initWithFrame:frame collectionViewLayout:layout]; if (self) { _allDayArray = [NSMutableArray array]; self.delegate = self; self.dataSource = self; self.backgroundColor = [UIColor whiteColor]; //set layout [self setLayOut]; // register [self registerClass:[YFCell class] forCellWithReuseIdentifier:@"cell"]; } return self; } - (void)setAllDayArray:(NSMutableArray *)allDayArray{ _allDayArray = allDayArray; [self reloadData]; } /** * set lauOut */ - (void)setLayOut{ UICollectionViewFlowLayout *layOut = [[UICollectionViewFlowLayout alloc]init]; layOut.itemSize = CGSizeMake(self.frame.size.width / 7, self.frame.size.height / 7); layOut.minimumLineSpacing = 0.0; layOut.minimumInteritemSpacing = 0.0; [self setCollectionViewLayout:layOut]; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return 35; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ YFCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath]; NSDictionary *dic = self.allDayArray[indexPath.row]; cell.dateLabel.text = [NSString stringWithFormat:@"%@",dic[@"day"]]; //农历,需要判断月份,年份 __weak typeof(self)weakSelf = self; __block NSString *lunarStr; if ([dic[@"status"] isEqualToString:@"pre"]) {//上一个月 [self changeCurrentMonth:_date andIndex:-1 resultData:^(NSDate *nowDate, NSString *showMonth) { SSLunarDate *sdate = [weakSelf lunarDaysString:nowDate int:[dic[@"day"] intValue]]; lunarStr = [NSString stringWithFormat:@"%@",[sdate dayString]]; }]; }else if ([dic[@"status"] isEqualToString:@"next"]){//下一个月 [self changeCurrentMonth:_date andIndex:1 resultData:^(NSDate *nowDate, NSString *showMonth) { SSLunarDate *sdate = [weakSelf lunarDaysString:nowDate int:[dic[@"day"] intValue]]; lunarStr = [NSString stringWithFormat:@"%@",[sdate dayString]]; }]; }else{ SSLunarDate *sdate = [self lunarDaysString:_date int:[dic[@"day"] intValue]]; lunarStr = [NSString stringWithFormat:@"%@",[sdate dayString]]; } cell.lunarLabel.text = lunarStr; return cell; } /** * 选择单元格 * * @param collectionView <#collectionView description#> * @param indexPath <#indexPath description#> */ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ NSDictionary *dic = self.allDayArray[indexPath.row]; NSLog(@"%li年 %i月 %i日 ",(long)[self currentYear:_date],[dic[@"month"] intValue],[dic[@"day"] intValue]); } @end
然后,用scrollview布局,可以左右滑动日历显示:
#import "ShowView.h" #import "YFCollectionView.h" #import "NSObject+CalenderSet.h" @interface ShowView() @property(nonatomic,strong)NSDate *date; @property(nonatomic,strong)YFCollectionView *leftCollectionView;//左侧 @property(nonatomic,strong)YFCollectionView *centerCollectionView;//中间 @property(nonatomic,strong)YFCollectionView *rightCollectionView;//右侧 @end @implementation ShowView /** * init * * @return <#return value description#> */ + (instancetype)createView{ return [[[NSBundle mainBundle]loadNibNamed:@"ShowView" owner:nil options:nil] lastObject]; } /** * set view */ - (void)awakeFromNib{ _date = [[NSDate alloc]init]; //显示的日期 [_centerBtn setTitle:[NSString stringWithFormat:@"%li年 %li月 %li日",[self currentYear:_date],[self currentMonth:_date],[self currentDay:_date]] forState:UIControlStateNormal]; _scrollView.pagingEnabled = YES; _scrollView.showsVerticalScrollIndicator = NO; _scrollView.showsHorizontalScrollIndicator = NO; _scrollView.contentSize = CGSizeMake(3 * _scrollView.frame.size.width, 0); // add collectionview for (int i = 0; i < 3; i ++) { YFCollectionView *collectionView = [[YFCollectionView alloc]initWithFrame:CGRectMake(i * _scrollView.frame.size.width, 0, _scrollView.frame.size.width, _scrollView.frame.size.height) collectionViewLayout:[[UICollectionViewFlowLayout alloc]init]]; collectionView.tag = i + 1001; [self.scrollView addSubview:collectionView]; } self.leftCollectionView = (YFCollectionView *)[self viewWithTag:1001]; self.centerCollectionView = (YFCollectionView *)[self viewWithTag:1002]; self.rightCollectionView = (YFCollectionView *)[self viewWithTag:1003]; //数据 self.centerCollectionView.date = _date; self.centerCollectionView.allDayArray = [self currentMonthArray:_date]; //左侧 [self changeCurrentMonth:_date andIndex:-1 resultData:^(NSDate *nowDate, NSString *showMonth) { self.leftCollectionView.date = nowDate; self.leftCollectionView.allDayArray = [self currentMonthArray:nowDate]; }]; //右侧 [self changeCurrentMonth:_date andIndex:1 resultData:^(NSDate *nowDate, NSString *showMonth) { self.rightCollectionView.date = nowDate; self.rightCollectionView.allDayArray = [self currentMonthArray:nowDate]; }]; self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width, 0); } /** * click pre btn * * @param sender <#sender description#> */ - (IBAction)clickPreBtn:(UIButton *)sender { [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x - self.scrollView.frame.size.width, 0) animated:YES]; } /** * clicknext btn * * @param sender <#sender description#> */ - (IBAction)clickNextBtn:(UIButton *)sender { [self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x + self.scrollView.frame.size.width, 0) animated:YES]; } /** * click center btn * * @param sender <#sender description#> */ - (IBAction)clickCenterBtn:(UIButton *)sender { } /** * scrollview delegate * */ - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ //判断 if (self.scrollView.contentOffset.x <= 0) { self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width, 0); //数据重新赋予 //中间数据 __weak typeof(self)weakSelf = self; [self changeCurrentMonth:_date andIndex:-1 resultData:^(NSDate *nowDate, NSString *showMonth) { self.centerCollectionView.date = nowDate; self.centerCollectionView.allDayArray = [self currentMonthArray:nowDate]; [weakSelf.centerBtn setTitle:showMonth forState:UIControlStateNormal]; weakSelf.date = nowDate; }]; //左侧 [self changeCurrentMonth:_date andIndex:-1 resultData:^(NSDate *nowDate, NSString *showMonth) { self.leftCollectionView.date = nowDate; self.leftCollectionView.allDayArray = [self currentMonthArray:nowDate]; }]; //右侧 [self changeCurrentMonth:_date andIndex:1 resultData:^(NSDate *nowDate, NSString *showMonth) { self.rightCollectionView.date = nowDate; self.rightCollectionView.allDayArray = [self currentMonthArray:nowDate]; }]; }else if (self.scrollView.contentOffset.x >= self.scrollView.frame.size.width * 2.0){ self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width, 0); //数据重新赋予 //中间数据 __weak typeof(self)weakSelf = self; [self changeCurrentMonth:_date andIndex:1 resultData:^(NSDate *nowDate, NSString *showMonth) { self.centerCollectionView.date = nowDate; self.centerCollectionView.allDayArray = [self currentMonthArray:nowDate]; [weakSelf.centerBtn setTitle:showMonth forState:UIControlStateNormal]; weakSelf.date = nowDate; }]; //左侧 [self changeCurrentMonth:_date andIndex:-1 resultData:^(NSDate *nowDate, NSString *showMonth) { self.leftCollectionView.date = nowDate; self.leftCollectionView.allDayArray = [self currentMonthArray:nowDate]; }]; //右侧 [self changeCurrentMonth:_date andIndex:1 resultData:^(NSDate *nowDate, NSString *showMonth) { self.rightCollectionView.date = nowDate; self.rightCollectionView.allDayArray = [self currentMonthArray:nowDate]; }]; } } @end
结语
我希望的是你可以根据我的代码思路,自己写出这一功能的代码。而不是让你直接command+c,command+v。请不要要你很忙,没有时间。Cheat ghost 。相关文章推荐
- Android布局的小窍门?
- Web布局连载——两栏固定布局(五)
- 样式表CSS布局经验
- 在winform下实现左右布局多窗口界面的方法之续篇
- css网页布局中注意的几个问题小结
- DL.DT.DD实现左右的布局简单例子第1/2页
- 使用CSS框架布局的缺点和优点小结
- div+CSS网页布局的意义与副作用原因小结第1/2页
- 在winform下实现左右布局多窗口界面的方法
- Android编程之代码创建布局实例分析
- jQuery支持添加事件的日历特效代码分享(3种样式)
- CSS顶级技巧大放送,div+css布局必知
- php简单日历函数
- 简单JavaScript日历及详细说明
- 兼容FireFox 的 js 日历 支持时间的获取
- js css+html实现简单的日历
- 用div实现像table一样的布局方法
- 精彩的Bootstrap案例分享 重点在注释!(选项卡、栅格布局)
- 基于javascript编写简单日历
- JavaScript制作简单的日历效果