您的位置:首页 > 其它

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 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  日历 布局