YFCalendar----最新版自写日历

简介

最新版的自己写的日历,有农历和阳历。
之前写的只是为了实现功能,没有注重代码的简洁性,这次我把代码进行了一定的分类封装。水平不够,多谢指教。
有需求的可以看看~~~~~,有能力的来个星星谢谢哈
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 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值