我们先看看效果图,是使用UICollectionView完成的一个日历的封装。
大家可以看到,这是使用UICollectionView完成的。日历可以上下滑动月数和年份,今天和过去的时间是可以操作的未来的时间为灰色,不可操作。日历支持选择时间点和时间段,都可以,选择时间段的时候,时间范围内的日期会高亮起来。
实现思路:好吧~日历的编写还是比较麻烦的,大家能借用到三方还是用三方吧。
1.使用分组的UICollectionView,每一个组头显示年份和月份,分组里边是每一天。
2.苹果系统内部自带有很多获取时间数据的方法,包括获取年份啊、月啊或者日,相关的时间数据方法,系统自带需要大家去了解查询。
3.从系统获取时间数据之后,我们会与今天的时间进行一个比较,早于今天的数据可以交互,文本高亮,晚于今天的时间,文本灰色,关闭交互。这在实现UICollectionView的- (UICollectionViewCell )collectionView:(UICollectionView )collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath协议方法的时候会进行一个比较复杂的逻辑判断。
4.实现选择时间范围的时候,我们会为自定义的UICollectionViewCell类编写一个外部可以调用的,刷新改变item颜色和文字的方法:
[cell reloadCellWithFirstDay:self.firstDay andLastDay:self.lastDay andCurrentDay:@[[NSNumber numberWithInteger:[components year]], [NSNumber numberWithInteger:[components month]], [NSNumber numberWithInteger:i - firstWeekDay + 1]]];
也就是上面这个方法,请大家特别注意。它是放在cellForItemAtIndexPath这个协议方法里面调用的,目的就是为了改变用户所选择的时间范围内的UI.它的具体实现在自定义UICollectionViewCell的内部,也是一个比较时间的过程。
5.主要给大家提供一个思路,大家有思路后,可以编写出更好看的日历控件。
好了,上代码
1.自定义UICollectionViewCell
.h
#import <UIKit/UIKit.h>
@interface CanderCollectionViewCell : UICollectionViewCell
@property (nonatomic,strong)UILabel *Label;
@property (nonatomic, strong)NSString *Flag;
//**参数1:开始时间,参数2:结束时间,参数3:当前cell时间;
- (void)reloadCellWithFirstDay:(NSArray *)firstDay andLastDay:(NSArray *)lastDay andCurrentDay:(NSArray *)currentDay;
@end
2.自定义UICollectionViewCell
.m
#import "CanderCollectionViewCell.h"
@implementation CanderCollectionViewCell
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self.contentView addSubview:self.Label];
}
return self;
}
- (UILabel *)Label
{
if (!_Label) {
_Label = [[UILabel alloc] initWithFrame:self.bounds];
[_Label setTextAlignment:NSTextAlignmentCenter];
[_Label setFont:[UIFont systemFontOfSize:[ZWFlexibieTool floatWithOriginalFloat:15.5 isFlexibleHeight:NO]]];
_Label.layer.masksToBounds = YES;
_Label.layer.cornerRadius = [ZWFlexibieTool floatWithOriginalFloat:5 isFlexibleHeight:NO];
}
return _Label;
}
- (void)reloadCellWithFirstDay:(NSArray *)firstDay andLastDay:(NSArray *)lastDay andCurrentDay:(NSArray *)currentDay{
//在空白的情况就让空白不显示
if (self.Label.text.length == 0) {
self.hidden = YES;
}else{
self.hidden = NO;
}
if ([firstDay isEqual:currentDay]) {//第三次点击的时候,改变点击的那个Cell颜色
self.Label.backgroundColor = COLOR_RGB(73, 105, 248);
self.Label.textColor = [UIColor whiteColor];
}else if (firstDay.count != 0 && lastDay.count != 0){//此处判断的是处于中间的
//三个日期
NSDate *FirstDate = [ZWTool stringToDate:[NSString stringWithFormat:@"%@-%@-%@",firstDay[0],firstDay[1],firstDay[2]] withDateFormat:@"yyyy-MM-dd"];
NSDate *LastDate = [ZWTool stringToDate:[NSString stringWithFormat:@"%@-%@-%@",lastDay[0],lastDay[1],lastDay[2]] withDateFormat:@"yyyy-MM-dd"];
NSDate *currentDate = [ZWTool stringToDate:[NSString stringWithFormat:@"%@-%@-%@",currentDay[0],currentDay[1],currentDay[2]] withDateFormat:@"yyyy-MM-dd"];
if ((currentDate > FirstDate && currentDate < LastDate) || (currentDate < FirstDate && currentDate > LastDate)) {
self.Label.backgroundColor = COLOR_RGB(127, 144, 219);
self.Label.textColor = [UIColor whiteColor];
}
if (currentDate == FirstDate || currentDate == LastDate) {
self.Label.backgroundColor = COLOR_RGB(73, 105, 248);
self.Label.textColor = [UIColor whiteColor];
}
}
}
3.自定义UICollectionView 的头部视图
.h
#import <UIKit/UIKit.h>
@interface CanderCollectionReusableView : UICollectionReusableView
@property (nonatomic, strong) UILabel *YerMonLabel;//年月展示标签
@property (nonatomic, strong) UIView *BehindView;
@end
4.自定义UICollectionView 的头部视图
.m
#import "CanderCollectionReusableView.h"
@implementation CanderCollectionReusableView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//加载视图
[self addSubview:self.BehindView];
[self.BehindView addSubview:self.YerMonLabel];
}
return self;
}
#pragma mark - Getter methods
- (UILabel *)YerMonLabel {
if (!_YerMonLabel) {
_YerMonLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 0, CGRectGetWidth(self.bounds), 30)];
_YerMonLabel.textAlignment = 0;
_YerMonLabel.textColor = [UIColor grayColor];
_YerMonLabel.backgroundColor = [UIColor whiteColor];
_YerMonLabel.font = [UIFont boldSystemFontOfSize:12];
}
return _YerMonLabel;
}
- (UIView *)BehindView{
if (!_BehindView) {
_BehindView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), 30)];
_BehindView.backgroundColor = [UIColor whiteColor];
}
return _BehindView;
}
@end
5.说明一下,日历我是封装在控制器当中的,具有一些回调协议用于传值,选择的时间范围不能超过一年,这是我具体工作中的要求,大家有思路后可以进行修改。
日历控制器.h
#import <UIKit/UIKit.h>
@protocol CanderViewControllerDelegate <NSObject>
@optional
//回传值到首页的协议
- (void)CanderViewControllerGiveWith:(NSString *)StartTime WithEndTime:(NSString *)EndTime;
@end
@interface CanderViewController : UIViewController
//设置代理
@property (nonatomic, weak) id <CanderViewControllerDelegate> delegate;
@property (nonatomic, strong) NSDateFormatter * formatter; //时间书写格式
@property (nonatomic, strong) NSDateComponents * components; //当前日期的零件
@property (nonatomic, strong) NSCalendar * calendar; //当前日历
@property (nonatomic, strong) NSArray * firstDay;//出发时间
@property (nonatomic, strong) NSArray * lastDay;//返回时间
//属性传值
@property (nonatomic, strong) NSString *StartValue;//接收主页回传时间值
@property (nonatomic, strong) NSString *EndValue;//接收主页回传时间值
@property (nonatomic, copy) NSString *EarningStr;
@end
日历控制器.m 这里有上千行代码,真的是太烦了~
#import "CanderViewController.h"
#import "CanderCollectionViewCell.h"
#import "CanderCollectionReusableView.h"//头部视图
@interface CanderViewController ()<UICollectionViewDataSource,UICollectionViewDelegate,UIGestureRecognizerDelegate>{
NSIndexPath *TodayIndexPath;//今日的表格路径
BOOL isFirst;
}
@property (nonatomic,strong)UICollectionView *CandercollectionView;
@property (nonatomic,strong)UICollectionViewFlowLayout *CanderflowLayout;
@property (nonatomic , strong) NSDate *date;//时间
@property (nonatomic , strong) NSDate *today;//今天的时间
@property (nonatomic, strong)UIButton *SureButton;//确定按钮
@property (nonatomic, strong)UILabel *StartLabel;//开始时间
@property (nonatomic, strong)UILabel *EndLabel;//结束时间
@property (nonatomic, strong)UIImageView *FlyImageView;//飞行图标
@property (nonatomic, strong)UITapGestureRecognizer *TapGester;//点击手势
@end
@implementation CanderViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"日期选择";
// self.tabBarController.tabBar.hidden = YES;//隐藏标签控制器
self.view.backgroundColor = [UIColor whiteColor];
self.date = [NSDate date];
self.today = self.date;//注意这里的时间给值方式,必须这么给值,不然后面的时间判断会出错。
[self.view addSubview:self.SureButton];
[self.view addSubview:self.CandercollectionView];
[self.view addSubview:self.EndLabel];
[self.view addSubview:self.StartLabel];
[self.view addSubview:self.FlyImageView];
[_SureButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.view.mas_left).offset(10);
make.right.mas_equalTo(self.view.mas_right).offset(-10);
make.bottom.mas_equalTo(self.view.mas_bottom).offset(-10);
make.height.mas_equalTo(45);
}];
[_CandercollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.view.mas_left).offset(0);
make.right.mas_equalTo(self.view.mas_right).offset(0);
make.bottom.mas_equalTo(_SureButton.mas_top).offset(-10);
make.top.mas_equalTo(_StartLabel.mas_bottom).offset(40);
}];
[_EndLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.mas_equalTo(self.view.mas_right).offset(-10);
make.top.mas_equalTo(self.view.mas_top).offset(15);
make.height.mas_equalTo(30);
make.width.mas_equalTo(130);
}];
[_StartLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.view.mas_left).offset(10);
make.top.mas_equalTo(self.view.mas_top).offset(15);
make.height.mas_equalTo(30);
make.width.mas_equalTo(130);
}];
[_FlyImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(_StartLabel.mas_right).offset(40);
make.top.mas_equalTo(self.view.mas_top).offset(20);
make.height.width.mas_equalTo(20);
}];
[self WeeksDayMethods];
}
- (void)WeeksDayMethods{
NSArray *WeekArr = @[@"SUN",@"MON",@"TUE",@"WED",@"THU",@"FRI",@"SAT"];
for (int i = 0; i < 7; i++) {
UILabel *label = [[UILabel alloc]init];
label.backgroundColor = [UIColor whiteColor];
label.textColor = COLOR_RGB(73, 105, 248);
label.textAlignment = 1;
label.text = [WeekArr objectAtIndex:i];
label.font = [UIFont boldSystemFontOfSize:[ZWFlexibieTool floatWithOriginalFloat:11 isFlexibleHeight:NO]];
[self.view addSubview:label];
[label mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(_StartLabel.mas_bottom).offset(15);
make.width.mas_equalTo(SCREEN_W/7);
make.height.mas_equalTo(25);
make.left.mas_equalTo(self.view.mas_left).offset(0+i*SCREEN_W/7);
}];
}
}
-(void)setDate:(NSDate *)date{
_date = date;
}
#pragma mark - 时间的方法.刘虎(下)----------------------------------------------------------
//得到今天是几号
- (NSInteger)day:(NSDate *)date{
NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date];
// NSLog(@"得到现在的这个时间是多少日%ld",(long)[components day]);
return [components day];
}
//得到今天是几月
- (NSInteger)month:(NSDate *)date{
NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date];
// NSLog(@"得到现在的这个时间是多少月%ld",(long)[components month]);
return [components month];
}
//得到今年是几年
- (NSInteger)year:(NSDate *)date{
NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date];
// NSLog(@"得到现在的这个时间是多少年%ld",(long)[components year]);
return [components year];
}
//计算每个月的第一天在星期几,从哪一个单元格开始。
- (NSInteger)firstWeekdayInThisMonth:(NSDate *)date{
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setFirstWeekday:1];//1.Sun. 2.Mon. 3.Thes. 4.Wed. 5.Thur. 6.Fri. 7.Sat.
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;
}
//这个月有多少天
- (NSInteger)totaldaysInThisMonth:(NSDate *)date{
NSRange totaldaysInMonth = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
// NSLog(@"这个月有几天%lu",(unsigned long)totaldaysInMonth.length);//看这个月有多少天
return totaldaysInMonth.length;
}
//上个月的date数据(用于刷新)
- (NSDate *)lastMonth:(NSDate *)date{
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
dateComponents.month = -1;//递归减一,上个月的数据
NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];
// NSLog(@"上个月的date数据 = %@",newDate);//比如现在是2016年7月1日,这里输出的是2016年6月1日
return newDate;
}
//下个月的date数据(用于刷新)
- (NSDate*)nextMonth:(NSDate *)date{
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
dateComponents.month = +1;//递归加一,下个月的数据
NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];
// NSLog(@"下个月的date数据 = %@",newDate);//比如现在是2016年7月1日,这里输出的是2016年8月1日
return newDate;
}
#pragma mark -------------------------时间的方法.刘虎(上)------------------------------------------------
#pragma mark -刘虎方法在于分别展示每个月的日历,网上方法在于很多年日历一起铺开。
#pragma mark - 集合视图协议方法
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 60;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
if ([self ReturnDaysNumeber:section] > 35) {
return 42;
}else{
return 35;
}
}
- (NSInteger)ReturnDaysNumeber:(NSInteger)Section{
//此方法就是在计算每个月的时间,为每个月数据的铺开创造条件
NSDate * dateTime = [self getEarlierAndLaterDaysFromDate:self.today withMonth:Section];
NSInteger daysInThisMonth = [self totaldaysInThisMonth:dateTime];//这个月有多少天
NSInteger firstWeekDay = [self firstWeekdayInThisMonth:dateTime];//计算每个月的第一天在星期几,从哪一个单元格开始。(可以确定从哪一行开始)
return daysInThisMonth+firstWeekDay;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSDate * dateTime = [self getEarlierAndLaterDaysFromDate:self.today withMonth:indexPath.section];
NSInteger dayIndex = indexPath.row - [self getBeginTimeInMonth:dateTime].integerValue + 1;
NSDateComponents *components = [self getCurrentComponentWithDate:dateTime];
NSInteger firstWeekDay = [self firstWeekdayInThisMonth:dateTime];//计算每个月的第一天在星期几,从哪一个单元格开始。(可以确定从哪一行开始)
//由于当前日期的cell处于选中状态,我们找到它,将它颜色变回来.这里需要判断路径是不是相同
if (![TodayIndexPath isEqual:indexPath]) {
CanderCollectionViewCell *Todaycell = (CanderCollectionViewCell *)[collectionView cellForItemAtIndexPath:TodayIndexPath];
Todaycell.Label.textColor = [UIColor blackColor];
Todaycell.Label.backgroundColor = [UIColor whiteColor];
Todaycell.Flag = @"0";
}
//数组有数据说明是上次预留,清空数据。
if (self.lastDay.count != 0 && self.firstDay.count != 0) {
self.firstDay = nil;
self.lastDay = nil;
}
//把开始和结束的时间给值
if (self.firstDay.count == 0) {
//第一次点击给值
self.firstDay = @[[NSNumber numberWithInteger:[components year]],[NSNumber numberWithInteger:[components month]],[NSNumber numberWithInteger:dayIndex-firstWeekDay]];
// NSLog(@"开始时间==%@",self.firstDay);
[self.SureButton setTitle:@"已选(0)天" forState:UIControlStateNormal];
[self.CandercollectionView reloadData];
}else {
//第二次点击给值
self.lastDay = @[[NSNumber numberWithInteger:[components year]],[NSNumber numberWithInteger:[components month]],[NSNumber numberWithInteger:dayIndex-firstWeekDay]];
[self CompareDateAndGiveValue:[NSString stringWithFormat:@"%@-%@-%@",self.firstDay[0],self.firstDay[1],self.firstDay[2]] With:[NSString stringWithFormat:@"%@-%@-%@",self.lastDay[0],self.lastDay[1],self.lastDay[2]]];
[self.CandercollectionView reloadData];
NSDate *FirstDate = [ZWTool stringToDate:[NSString stringWithFormat:@"%@-%@-%@",self.firstDay[0],self.firstDay[1],self.firstDay[2]] withDateFormat:@"yyyy-MM-dd"];
NSDate *LastDate = [ZWTool stringToDate:[NSString stringWithFormat:@"%@-%@-%@",self.lastDay[0],self.lastDay[1],self.lastDay[2]] withDateFormat:@"yyyy-MM-dd"];
//计算两个中间差值(秒)
NSTimeInterval time = [LastDate timeIntervalSinceDate:FirstDate];
//开始时间和结束时间的中间相差的时间
int days;
days = ((int)time)/(3600*24)+1; //一天是24小时*3600秒
if (days < 0) {
days = days *-1;
}
NSString * dateValue = [NSString stringWithFormat:@"%i",days];
[self.SureButton setTitle:[NSString stringWithFormat:@"已选(%@)天",dateValue] forState:UIControlStateNormal];
}
//这里找到的是那个被选中的cell
CanderCollectionViewCell *cell = (CanderCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
cell.Label.backgroundColor = [UIColor blueColor];
cell.Label.textColor = [UIColor whiteColor];
cell.Flag = @"1";
}
- (void)CompareDateAndGiveValue:(NSString *)StartStr With:(NSString *)EndStr{
NSDate *DateOne = [ZWTool stringToDate:StartStr withDateFormat:@"yyyy-MM-dd"];
NSDate *DateTwo = [ZWTool stringToDate:EndStr withDateFormat:@"yyyy-MM-dd"];
if ([DateOne compare:DateTwo] == NSOrderedAscending) {//左边的小于右边的
self.StartLabel.text = StartStr;
self.EndLabel.text = EndStr;
}else if ([DateOne compare:DateTwo] == NSOrderedSame){//这里是两次的时间都一样
self.StartLabel.text = StartStr;
self.EndLabel.text = EndStr;
}
else{
self.StartLabel.text = EndStr;
self.EndLabel.text = StartStr;
}
}
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
CanderCollectionViewCell *cell = (CanderCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
cell.Label.backgroundColor = [UIColor whiteColor];
cell.Label.textColor = [UIColor blackColor];
cell.Flag = @"0";
}
//头部视图
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
//重用
CanderCollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CanderHeader" forIndexPath:indexPath];
NSArray *HeadDateArr = (NSArray *)[self getTimeFormatArrayWithDate:self.today andMonth:indexPath.section];
headerView.YerMonLabel.text = [NSString stringWithFormat:@"%@年%@月",HeadDateArr[0],HeadDateArr[1]];
return headerView;
}
#pragma mark -------------------------网上方法(下)------------------------------------------------
/**获取每个单位内开始时间*/
- (NSString *)getBeginTimeInMonth:(NSDate *)date {
NSTimeInterval count = 0;
NSDate * beginDate = nil;
NSCalendar * calendar = [NSCalendar currentCalendar];
//返回日历每个月份的开始时间,类型是unitMonth
BOOL findFirstTime = [calendar rangeOfUnit:NSCalendarUnitMonth startDate:&beginDate interval:&count forDate:date];
if (findFirstTime) {
return nil;
}else {
return @"";
}
}
/**获取当前日期格式*/
- (NSArray *)getTimeFormatArrayWithDate:(NSDate *)date andMonth:(NSInteger)month {
NSDate * dateTime = [self getEarlierAndLaterDaysFromDate:self.today withMonth:month];
NSString * stringFormat = [self.formatter stringFromDate:dateTime];
//通过“-”拆分日期格式
return [stringFormat componentsSeparatedByString:@"-"];
}
//**根据当前时间获取当前和以后各有多少个月,0为当前月*/
- (NSDate *)getEarlierAndLaterDaysFromDate:(NSDate *)date withMonth:(NSInteger)month {
NSDate * newDate = [NSDate date];
NSDateComponents * components = [self getCurrentComponentWithDate:newDate];
//获取section表示的每个月份
NSInteger year = [components year];
NSInteger month_n = [components month];
//希望从哪年开始写日历 例如2016年
NSInteger month_count = (year - 2015) * 12;
//获取当前section代表的月份和现在月份的差值
NSInteger months = month - month_count - month_n + 1;
[self.components setMonth:months];
//返回各月份的当前日期,如:2016-01-14,2016-02-14
NSDate * ndate = [self.calendar dateByAddingComponents:self.components toDate:date options:0];
return ndate;
}
/**获取当前日期零件*/
- (NSDateComponents *)getCurrentComponentWithDate:(NSDate *)dateTime {
NSCalendar * calendar = [NSCalendar currentCalendar];
//日期拆分类型
NSCalendarUnit unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitDay;
return [calendar components:unitFlags fromDate:dateTime];
}
- (NSDateFormatter *)formatter {
if (!_formatter) {
_formatter = [[NSDateFormatter alloc] init];
_formatter.dateFormat = @"yyyy-MM-dd";
}
return _formatter;
}
- (NSDateComponents *)components {
if (!_components) {
_components = [[NSDateComponents alloc] init];
}
return _components;
}
- (NSCalendar *)calendar {
if (!_calendar) {
_calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
}
return _calendar;
}
//这里的功能是让日历定位到今天所在的那个月。
- (void)viewDidLayoutSubviews{
if (isFirst == NO) {
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:now];
NSInteger year = [dateComponent year];
NSInteger month1 = [dateComponent month];
NSInteger day = [dateComponent day];
//NSInteger hour = [dateComponent hour];
//NSInteger minute = [dateComponent minute];
//NSInteger second = [dateComponent second];
//这里写的2015,就是2015年一月一日开始
NSInteger months = (year - 2015) * 12 + month1 - 1;
[self.CandercollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:day inSection:months] atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];
isFirst = YES;
}else{
return;
}
}
#pragma mark --------------------------网上方法(上)----------------------------------------------
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CanderCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
cell.Flag = @"0";
//此方法就是在计算每个月的时间,为每个月数据的铺开创造条件
NSDate * dateTime = [self getEarlierAndLaterDaysFromDate:self.today withMonth:indexPath.section];
NSInteger daysInThisMonth = [self totaldaysInThisMonth:dateTime];//这个月有多少天
NSInteger firstWeekDay = [self firstWeekdayInThisMonth:dateTime];//计算每个月的第一天在星期几,从哪一个单元格开始。(可以确定从哪一行开始)
NSInteger day = 0;
NSInteger i = indexPath.row;
//小于第一天所在的行数
if (i < firstWeekDay) {
cell.Label.text = @"";//集合视图,i为重用的时候,当前的item数,当i小于第一天所在的行数的时候,文本为空。
cell.Label.backgroundColor = [UIColor whiteColor];
//大于第一天所在的行数
}else if (i > firstWeekDay + daysInThisMonth - 1){
cell.Label.text = @"";//同理集合视图,i为重用的时候,当前的item数,当i大于第一天所在的行数的时候,文本为空。
cell.Label.backgroundColor = [UIColor whiteColor];
}else{
//中间的
day = i - firstWeekDay + 1;//计算每个item需要显示的数字文本
cell.Label.text = [NSString stringWithFormat:@"%ld",(long)day];//给每个item文本给值
//cell重用的时候的颜色设置
if ([cell.Flag isEqualToString:@"1"]) {
cell.Label.backgroundColor = COLOR_RGB(73, 105, 248);
cell.Label.textColor = [UIColor whiteColor];
}else{
cell.Label.backgroundColor = [UIColor whiteColor];
cell.Label.textColor = [UIColor blackColor];
}
if ([_today isEqualToDate:dateTime]) {//这是在处理本日所在的月份的这一组集合视图的样式。
if (day == [self day:dateTime]) {//[self day:_date]是得到今天是几号的方法,如果今天的日期刚好等于day,那么文本为红色
cell.Label.text = @"今天";
cell.Label.textColor = [UIColor whiteColor];
cell.Label.backgroundColor = COLOR_RGB(231, 88, 84);
//记录当前的日期的Cell的NSIndexPath
TodayIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
//让当前日期的cell处于选中状态
// cell.Flag = @"1";
}else if (day > [self day:dateTime]){//如果是大于的话就是暗灰色。
cell.Label.textColor = [UIColor lightGrayColor];
}
}else if ([_today compare:dateTime] == NSOrderedAscending){//这是在处理未来时间,也就是未来的时间月份的样式
//NSOrderedAscending的意思是:左边的操作对象小于右边的对象。
//NSOrderedDescending的意思是:左边的操作对象大于右边的对象。
cell.Label.backgroundColor = [UIColor whiteColor];
cell.Label.textColor = [UIColor lightGrayColor];//此代码指的是未来的时间的文本颜色。
cell.userInteractionEnabled = NO;//未来时间不允许选取
}
}
if (cell.Label.text.length == 0 || [cell.Label.textColor isEqual:[UIColor lightGrayColor]]) {
cell.userInteractionEnabled = NO;
}else{
cell.userInteractionEnabled = YES;
}
//刷新UI控件
NSDateComponents * components = [self getCurrentComponentWithDate:dateTime];
[cell reloadCellWithFirstDay:self.firstDay andLastDay:self.lastDay andCurrentDay:@[[NSNumber numberWithInteger:[components year]], [NSNumber numberWithInteger:[components month]], [NSNumber numberWithInteger:i - firstWeekDay + 1]]];
return cell;
}
- (UICollectionViewFlowLayout *)CanderflowLayout{
if (!_CanderflowLayout) {
_CanderflowLayout = [[UICollectionViewFlowLayout alloc]init];
_CanderflowLayout.minimumInteritemSpacing = [ZWFlexibieTool floatWithOriginalFloat:2 isFlexibleHeight:NO];
_CanderflowLayout.minimumLineSpacing = [ZWFlexibieTool floatWithOriginalFloat:5 isFlexibleHeight:NO];
_CanderflowLayout.itemSize = CGSizeMake([ZWFlexibieTool floatWithOriginalFloat:50 isFlexibleHeight:NO], [ZWFlexibieTool floatWithOriginalFloat:50 isFlexibleHeight:NO]);
_CanderflowLayout.sectionInset = UIEdgeInsetsMake([ZWFlexibieTool floatWithOriginalFloat:5 isFlexibleHeight:NO], [ZWFlexibieTool floatWithOriginalFloat:5 isFlexibleHeight:NO], [ZWFlexibieTool floatWithOriginalFloat:5 isFlexibleHeight:NO], [ZWFlexibieTool floatWithOriginalFloat:5 isFlexibleHeight:NO]);
//设置头部视图的高度
_CanderflowLayout.headerReferenceSize = CGSizeMake(CGRectGetWidth(self.view.bounds), 44);
_CanderflowLayout.sectionHeadersPinToVisibleBounds = NO;
}
return _CanderflowLayout;
}
- (UICollectionView *)CandercollectionView{
if (!_CandercollectionView) {
_CandercollectionView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:self.CanderflowLayout];
[_CandercollectionView registerClass:[CanderCollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
_CandercollectionView.delegate = self;
_CandercollectionView.dataSource = self;
_CandercollectionView.bounces = NO;
_CandercollectionView.backgroundColor = [UIColor whiteColor];
[_CandercollectionView registerClass:[CanderCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CanderHeader"];
}
return _CandercollectionView;
}
- (UIButton *)SureButton{
if (!_SureButton) {
_SureButton = [[UIButton alloc]init];
_SureButton.backgroundColor = COLOR_RGB(73, 105, 248);
[_SureButton setTitle:@"已选(0)天" forState:UIControlStateNormal];
[_SureButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_SureButton addTarget:self action:@selector(respondsToSureButton:) forControlEvents:UIControlEventTouchUpInside];
_SureButton.layer.masksToBounds = YES;
_SureButton.layer.cornerRadius = 3;
}
return _SureButton;
}
//开始时间
- (UILabel *)StartLabel{
if (!_StartLabel) {
_StartLabel = [[UILabel alloc]init];
_StartLabel.backgroundColor = COLOR_RGB(73, 105, 248);
_StartLabel.textAlignment = 1;
_StartLabel.tag = 1;
if (self.StartValue.length > 0) {
_StartLabel.text = self.StartValue;
}else{
_StartLabel.text = [self getStartTimeStr];
}
_StartLabel.textColor = [UIColor whiteColor];
_StartLabel.layer.masksToBounds = YES;
_StartLabel.layer.cornerRadius = 3;
_StartLabel.font = [UIFont systemFontOfSize:[ZWFlexibieTool floatWithOriginalFloat:12 isFlexibleHeight:NO]];
_StartLabel.userInteractionEnabled = YES;
//添加手势
[_StartLabel addGestureRecognizer:self.TapGester];
}
return _StartLabel;
}
//结束时间
- (UILabel *)EndLabel{
if (!_EndLabel) {
_EndLabel = [[UILabel alloc]init];
_EndLabel.backgroundColor = COLOR_RGB(73, 105, 248);
_EndLabel.textAlignment = 1;
_EndLabel.tag = 2;
if (self.EndValue.length > 0) {
_EndLabel.text = self.EndValue;
}else{
_EndLabel.text = [self getEndTimeStr];
}
_EndLabel.textColor = [UIColor whiteColor];
_EndLabel.layer.masksToBounds = YES;
_EndLabel.layer.cornerRadius = 3;
_EndLabel.font = [UIFont systemFontOfSize:[ZWFlexibieTool floatWithOriginalFloat:12 isFlexibleHeight:NO]];
_EndLabel.userInteractionEnabled = YES;
UITapGestureRecognizer *Gester = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToTapGestureRecognizer:)];
// 设置点击次数
Gester.numberOfTapsRequired = 1;
// 设置手指数量
Gester.numberOfTouchesRequired = 1;
Gester.delegate = self;
[_EndLabel addGestureRecognizer:Gester];
}
return _EndLabel;
}
- (UITapGestureRecognizer *)TapGester{
if (!_TapGester) {
_TapGester = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(respondsToTapGestureRecognizer:)];
// 设置点击次数
_TapGester.numberOfTapsRequired = 1;
// 设置手指数量
_TapGester.numberOfTouchesRequired = 1;
_TapGester.delegate = self;
}
return _TapGester;
}
//点击手势事件
- (void)respondsToTapGestureRecognizer:(UITapGestureRecognizer *)gesture {
UIDatePicker *picker = [[UIDatePicker alloc]init];
picker.datePickerMode = UIDatePickerModeDate;
NSLocale *locale = [[NSLocale alloc]initWithLocaleIdentifier:@"zh_CN"];//设置为中文显示
picker.locale = locale;//可以设置本地手机的现实模式
[picker setDate:[NSDate date] animated:YES];//设置当前显示日期
picker.frame = CGRectMake(0, 30, 350, 200);
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"日期选择\n\n\n\n\n\n\n\n\n\n" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
NSDate *senddate=picker.date;
NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init];
[dateformatter setDateFormat:@"YYYY-MM-dd"];
NSString *ChooseString=[dateformatter stringFromDate:senddate];
if (gesture.view.tag == 1) {//开始文本
//判断选择的时间是否合法
NSDate *DateOne = [ZWTool stringToDate:ChooseString withDateFormat:@"yyyy-MM-dd"];
NSDate *DateTwo = [ZWTool stringToDate:self.EndLabel.text withDateFormat:@"yyyy-MM-dd"];
if ([DateOne compare:DateTwo] == NSOrderedAscending) {//左边的小于右边的
self.StartLabel.text = ChooseString;
//计算两个中间差值(秒)
NSTimeInterval time = [DateOne timeIntervalSinceDate:DateTwo];
//开始时间和结束时间的中间相差的时间
int days;
days = ((int)time)/(3600*24)+1; //一天是24小时*3600秒
if (days < 0) {
days = days *-1;
}
NSString * dateValue = [NSString stringWithFormat:@"%i",days];
[self.SureButton setTitle:[NSString stringWithFormat:@"已选(%@)天",dateValue] forState:UIControlStateNormal];
}else if ([DateOne compare:DateTwo] == NSOrderedSame){//这里是两次的时间都一样
self.StartLabel.text = ChooseString;
[self.SureButton setTitle:@"已选(1)天" forState:UIControlStateNormal];
}
else{
UIAlertController *alretController = [UIAlertController alertControllerWithTitle:@"数聚空港" message:@"结束时间不能早于开始时间" preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alretController animated:YES completion:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:nil];
});
}];
}
}else{//结束文本
//判断选择的时间是否合法
NSDate *DateOne = [ZWTool stringToDate:self.StartLabel.text withDateFormat:@"yyyy-MM-dd"];
NSDate *DateTwo = [ZWTool stringToDate:ChooseString withDateFormat:@"yyyy-MM-dd"];
if ([DateOne compare:DateTwo] == NSOrderedAscending) {//左边的小于右边的
self.EndLabel.text = ChooseString;
//计算两个中间差值(秒)
NSTimeInterval time = [DateOne timeIntervalSinceDate:DateTwo];
//开始时间和结束时间的中间相差的时间
int days;
days = ((int)time)/(3600*24)+1; //一天是24小时*3600秒
if (days < 0) {
days = days *-1;
}
NSString * dateValue = [NSString stringWithFormat:@"%i",days];
[self.SureButton setTitle:[NSString stringWithFormat:@"已选(%@)天",dateValue] forState:UIControlStateNormal];
}else if ([DateOne compare:DateTwo] == NSOrderedSame){//这里是两次的时间都一样
self.EndLabel.text = ChooseString;
[self.SureButton setTitle:@"已选(1)天" forState:UIControlStateNormal];
}
else{
UIAlertController *alretController = [UIAlertController alertControllerWithTitle:@"数聚空港" message:@"结束时间不能早于开始时间" preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alretController animated:YES completion:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:nil];
});
}];
}
}
}];
[alertController.view addSubview:picker];
[alertController addAction:cancelAction];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:alertController animated:YES completion:nil];
});
}
- (UIImageView *)FlyImageView{
if (!_FlyImageView) {
_FlyImageView = [[UIImageView alloc]init];
_FlyImageView.image = [UIImage imageNamed:@"日历_image_disabled.png"];
}
return _FlyImageView;
}
//得到结束时间
- (NSString *)getEndTimeStr{
//昨天的时间
NSDate *Enddate=[NSDate date];
NSTimeInterval time = 24 * 60 * 60;//一天的秒数
NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init];
NSDate *lastDay = [Enddate dateByAddingTimeInterval:-time];
[dateformatter setDateFormat:@"YYYY-MM-dd"];
return [dateformatter stringFromDate:lastDay];
}
//得到开始的时间(倒数60天)
- (NSString *)getStartTimeStr{
//获取系统时间
NSDate *Enddate=[NSDate date];
NSTimeInterval time = 24 * 60 * 60;//一天的秒数
NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init];
NSDate *lastDay = [Enddate dateByAddingTimeInterval:-time*60];
[dateformatter setDateFormat:@"YYYY-MM-dd"];
return [dateformatter stringFromDate:lastDay];
}
//确定按钮事件
- (void)respondsToSureButton:(UIButton *)sender{
if (self.StartLabel.text.length > 0 && self.EndLabel.text.length > 0 && ![self.EndLabel.text isEqualToString:@"请选择结束时间"]) {
NSDate *FirstDate = [ZWTool stringToDate:[NSString stringWithFormat:@"%@-%@-%@",self.firstDay[0],self.firstDay[1],self.firstDay[2]] withDateFormat:@"yyyy-MM-dd"];
NSDate *LastDate = [ZWTool stringToDate:[NSString stringWithFormat:@"%@-%@-%@",self.lastDay[0],self.lastDay[1],self.lastDay[2]] withDateFormat:@"yyyy-MM-dd"];
//计算两个中间差值(秒)
NSTimeInterval time = [LastDate timeIntervalSinceDate:FirstDate];
//开始时间和结束时间的中间相差的时间
int days;
days = ((int)time)/(3600*24)+1; //一天是24小时*3600秒
if (days < 0) {
days = days *-1;
}
if (days > 366) {
UIAlertController *alretController = [UIAlertController alertControllerWithTitle:@"数聚空港" message:@"时间跨度选择不能超过一年,请重新选择" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//数组有数据说明是上次预留,清空数据。
if (self.lastDay.count != 0 && self.firstDay.count != 0) {
self.firstDay = nil;
self.lastDay = nil;
}
[self.CandercollectionView reloadData];
[self.SureButton setTitle:@"已选(0)天" forState:UIControlStateNormal];
}];
[alretController addAction:sureAction];
[self presentViewController:alretController animated:YES completion:nil];
}else{
//将时间值传递到首页,如果客户选择时间值发生变化,首页会将值再次传递到日历控件。
if (_delegate && [_delegate respondsToSelector:@selector(CanderViewControllerGiveWith:WithEndTime:)]) {
[_delegate CanderViewControllerGiveWith:self.StartLabel.text WithEndTime:self.EndLabel.text];
}
NSDictionary *userInfo = @{@"StartDate":self.StartLabel.text, @"EndDate":self.EndLabel.text};
if ([self.EarningStr isEqualToString:@"收益"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"CanderEarningDateNotification" object:nil userInfo:userInfo];
[self.navigationController popViewControllerAnimated:YES];
}else if ([self.EarningStr isEqualToString:@"航班详情"]){
[[NSNotificationCenter defaultCenter] postNotificationName:@"FlightDetailNotification" object:nil userInfo:userInfo];
[self.navigationController popViewControllerAnimated:YES];
}
else{
if ([self.EarningStr isEqualToString:@"准点率"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"CanderZhunDianLvNotification" object:nil userInfo:userInfo];
[self.navigationController popViewControllerAnimated:YES];
}else{
//发送通知传递时间给四个页面,让四个子页面数据刷新。
[[NSNotificationCenter defaultCenter] postNotificationName:@"CanderDateNotification" object:nil userInfo:userInfo];
[self.navigationController popViewControllerAnimated:YES];
}
}
}
}else{
UIAlertController *alretController = [UIAlertController alertControllerWithTitle:@"数聚空港" message:@"开始或结束时间不能为空" preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alretController animated:YES completion:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:nil];
});
}];
}
}
@end