iOS 日历 签到功能
公司APP涉及到签到功能,具体以当前日期为分界线。
也就是今天之前的日期分为已签到和未签到并且未签到可以补签(涉及到3种UI效果)。今天分为已签到和未签到(2种UI效果),今天以后的显示为日期(1种UI效果)。
下面是效果图奉上。
红色部分为组头,显示的是当前年月。
绿色部分是当前月份的日期以及之前的日期。
数字部分为当前日期后面的日期。
这样就可以自定义出来今天日期之前的日期是否签到。
下面是具体代码实现。
直接新建工程,在新工程的viewcontroller.m里面直接拷贝如下代码:
#import "ViewController.h"
#import "NSDate+LYWCalendar.h"
#import "LYWCollectionViewCell.h"
#import "LYWCollectionReusableView.h"
#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
#define NumberMounthes 1
@interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>{
//自动布局
UICollectionViewFlowLayout *_layout;
//表格视图
UICollectionView *_collectionView;
//当月第一天星期几
NSInteger firstDayInMounthInWeekly;
NSMutableArray *_firstMounth;
NSMutableArray *_dateArray;
}
@end
static NSString *cellID =@"cellID";
static NSString *headerID =@"headerID";
static NSString *footerID =@"footerID";
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
self.automaticallyAdjustsScrollViewInsets =NO;//关闭自动适应
NSArray *weekTitleArray =@[@"日",@"一",@"二",@"三",@"四",@"五",@"六"];
for (int i =0; i < weekTitleArray.count; i++) {
UILabel *weekTitleLable = [[UILabelalloc]initWithFrame:CGRectMake(i * ((ScreenWidth/(weekTitleArray.count))),64,ScreenWidth/(weekTitleArray.count ),30)];
if (i ==0 || i ==6) {
weekTitleLable.textColor = [UIColorblackColor];
}else{
weekTitleLable.textColor = [UIColorblackColor];
}
weekTitleLable.text = [weekTitleArrayobjectAtIndex:i];
weekTitleLable.textAlignment =NSTextAlignmentCenter;
[self.viewaddSubview:weekTitleLable];
}
[selfcreateData];
[selfcreateCollectionView];
}
-(void)createCollectionView{
//设置collectionView及自动布局,代理方法尤为重要
_layout = [[UICollectionViewFlowLayoutalloc]init];
//头部始终在顶端
_layout.sectionHeadersPinToVisibleBounds =YES;
//头部视图高度
_layout.headerReferenceSize =CGSizeMake(414,40);
_layout.minimumLineSpacing =0;
_layout.minimumInteritemSpacing =0;
_collectionView = [[UICollectionViewalloc]initWithFrame:CGRectMake(0,64 + 30, ScreenWidth,ScreenHeight -64 -30)collectionViewLayout:_layout];
_collectionView.backgroundColor = [UIColorwhiteColor];
//注册表格
[_collectionViewregisterClass:[LYWCollectionViewCellclass]forCellWithReuseIdentifier:cellID];
//注册头视图
[_collectionViewregisterClass:[LYWCollectionReusableViewclass]forSupplementaryViewOfKind:UICollectionElementKindSectionHeaderwithReuseIdentifier:headerID];
_collectionView.delegate =self;
_collectionView.dataSource =self;
//注册尾视图
// [_collectionView registerClass:[UICollectionReusableView class] forCellWithReuseIdentifier:footerID];
[self.viewaddSubview:_collectionView];
}
-(void)createData{
_dateArray = [[NSMutableArrayalloc]init];
NSDate *currentDate = [[NSDatealloc]init];
int daysInMounth = (int)[currentDatetotaldaysInMonth:currentDate];
//获取月份
int mounth = ((int)[currentDatemonth:currentDate])%12;
NSDateComponents *components = [[NSDateComponentsalloc]init];
//获取下个月的年月日信息,并将其转为date
components.month = mounth;
components.year = [currentDateyear:currentDate];
components.day =1;
NSCalendar *calendar = [NSCalendarcurrentCalendar];
NSDate *nextDate = [calendardateFromComponents:components];
//获取该月第一天星期几
NSInteger firstDayInThisMounth = [nextDatefirstWeekdayInThisMonth:nextDate];
//该月的有多少天daysInThisMounth
NSInteger daysInThisMounth = [nextDatetotaldaysInMonth:nextDate];
NSString *string = [[NSStringalloc]init];
for (int j =0; j < (daysInMounth >29 && (firstDayInThisMounth ==6 || firstDayInThisMounth ==5) ?42 :35) ; j++) {
if (j < firstDayInThisMounth || j > daysInThisMounth + firstDayInThisMounth -1) {
string = @"";
[_dateArray addObject:string];
}else{
string = [NSStringstringWithFormat:@"%ld",j - firstDayInThisMounth +1];
[_dateArray addObject:string];
}
}
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return _dateArray.count;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
//这里是自定义cell,非常简单的自定义
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
LYWCollectionViewCell *cell = [collectionViewdequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
UIView *blackgroundView = [[UIViewalloc]initWithFrame:CGRectMake(0,0, cell.frame.size.width, cell.frame.size.height)];
blackgroundView.backgroundColor = [UIColoryellowColor];
NSDate *date = [[NSDatealloc]init];
NSInteger day = [dateday:date];
cell.dateLable.text = [_dateArray objectAtIndex:indexPath.row];
if ([cell.dateLable.textisEqualToString:@""]) {
cell.dateView.backgroundColor = [UIColorclearColor];
cell.dateLable.hidden =YES;
cell.dateView.hidden =NO;
}elseif([cell.dateLable.textintegerValue] !=0 && [cell.dateLable.textintegerValue]<=day){
cell.dateView.backgroundColor = [UIColorgreenColor];
cell.dateLable.hidden =YES;
cell.dateView.hidden =NO;
}else{
cell.dateLable.hidden =NO;
cell.dateView.hidden =YES;
}
cell.selectedBackgroundView = blackgroundView;
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
returnCGSizeMake(ScreenWidth/7,ScreenWidth/7);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
returnUIEdgeInsetsMake(0,0,0,0);
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
if (kind ==UICollectionElementKindSectionHeader) {
LYWCollectionReusableView *headerRV = [collectionViewdequeueReusableSupplementaryViewOfKind:kindwithReuseIdentifier:headerID forIndexPath:indexPath];
//自定义蓝色
headerRV.backgroundColor = [UIColor redColor];
NSDate *currentDate = [[NSDate alloc]init];
NSInteger year = [currentDate year:currentDate];
NSInteger mounth = ([currentDate month:currentDate] + indexPath.section) %12 == 0 ?12 : ([currentDatemonth:currentDate] + indexPath.section)%12;
headerRV.dateLable.text = [NSStringstringWithFormat:@"%ld年%ld月",year,mounth];
return headerRV;
}else{
return nil;
}
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
LYWCollectionViewCell *cell = [self collectionView:_collectionView cellForItemAtIndexPath:indexPath];
NSDate *currentDate = [[NSDate alloc]init];
//打印当前日期
if (![cell.dateLable.textisEqualToString:@""]) {
NSInteger year = ([currentDate month:currentDate] + indexPath.section)/12 +2016;
NSInteger mounth = ([currentDate month:currentDate] + indexPath.section)%12;
NSInteger day = [cell.dateLable.textintValue];
NSLog(@"%ld年%02ld月%02ld日",year,mounth,day);
}
//排除空值cell
//获取月份
NSInteger mounth = ([currentDatemonth:currentDate] + indexPath.section) %12 == 0 ?12 : ([currentDatemonth:currentDate] + indexPath.section)%12;
NSDateComponents *components = [[NSDateComponents alloc]init];
components.month = mounth;
components.year = [currentDate year:currentDate];
components.day =1;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *nextDate = [calendar dateFromComponents:components];
//获取该月第一天星期几
NSInteger firstDayInThisMounth = [nextDate firstWeekdayInThisMonth:nextDate];
//该月的有多少天daysInThisMounth
NSInteger daysInThisMounth = [nextDate totaldaysInMonth:nextDate];
if ((indexPath.row < firstDayInThisMounth || indexPath.row > daysInThisMounth + firstDayInThisMounth - 1)){
//如果点击空表格则单击无效
[collectionView cellForItemAtIndexPath:indexPath].userInteractionEnabled =NO;
[collectionView reloadData];
}
}
下面是几个头文件里面的内容
NSDate+LYWCalendar.h,这个是一个类别,需要自己创建
#import <Foundation/Foundation.h>
@interface NSDate (LYWCalendar)
#pragma mark - 获取日
- (NSInteger)day:(NSDate *)date;
#pragma mark - 获取月
- (NSInteger)month:(NSDate *)date;
#pragma mark - 获取年
- (NSInteger)year:(NSDate *)date;
#pragma mark - 获取当月第一天周几
- (NSInteger)firstWeekdayInThisMonth:(NSDate *)date;
#pragma mark - 获取当前月有多少天
- (NSInteger)totaldaysInMonth:(NSDate *)date;
@end
#import "NSDate+LYWCalendar.h"
@implementation NSDate (LYWCalendar)
/**
*实现部分
*/
#pragma mark -- 获取日
- (NSInteger)day:(NSDate *)date{
NSDateComponents *components = [[NSCalendar currentCalendar]components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay)fromDate:date];
return components.day;
}
#pragma mark -- 获取月
- (NSInteger)month:(NSDate *)date{
NSDateComponents *components = [[NSCalendar currentCalendar]components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay)fromDate:date];
return components.month;
}
#pragma mark -- 获取年
- (NSInteger)year:(NSDate *)date{
NSDateComponents *components = [[NSCalendar currentCalendar]components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay)fromDate:date];
return components.year;
}
#pragma mark -- 获得当前月份第一天星期几
- (NSInteger)firstWeekdayInThisMonth:(NSDate *)date{
NSCalendar *calendar = [NSCalendar currentCalendar];
//设置每周的第一天从周几开始,默认为1,从周日开始
[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;
}
#pragma mark -- 获取当前月共有多少天
- (NSInteger)totaldaysInMonth:(NSDate *)date{
NSRange daysInLastMonth = [[NSCalendarcurrentCalendar] rangeOfUnit:NSCalendarUnitDayinUnit:NSCalendarUnitMonthforDate:date];
return daysInLastMonth.length;
}
@end
LYWCollectionViewCell.h
#import <UIKit/UIKit.h>
@interface LYWCollectionViewCell :UICollectionViewCell
@property (nonatomic,strong)UILabel *dateLable;
@property (nonatomic,strong)UIImageView *dateView;
- (id)initWithFrame:(CGRect)frame;
@end
LYWCollectionViewCell.m
#import "LYWCollectionViewCell.h"
@implementation LYWCollectionViewCell
- (id)initWithFrame:(CGRect)frame{
if (self == [superinitWithFrame:frame]) {
_dateLable = [[UILabelalloc]initWithFrame:self.bounds];
[_dateLablesetTextAlignment:NSTextAlignmentCenter];
[_dateLablesetFont:[UIFontsystemFontOfSize:17]];
_dateLable.textColor = [UIColorblackColor];
[selfaddSubview:_dateLable];
self.dateView = [[UIImageView alloc]initWithFrame:self.bounds];
CGFloat red =arc4random()%255/256.0f;
CGFloat green =arc4random()%255/256.0f;
CGFloat blue =arc4random()%255/256.0f;
self.dateView.backgroundColor = [UIColor colorWithRed:redgreen:greenblue:bluealpha:1];
[self.contentViewaddSubview:_dateView];
}
returnself;
}
@end
LYWCollectionReusableView.h
#import <UIKit/UIKit.h>
@interface LYWCollectionReusableView :UICollectionReusableView
@property (nonatomic,strong)UILabel *dateLable;
- (instancetype)initWithFrame:(CGRect)frame;
@end
LYWCollectionReusableView.m
#import "LYWCollectionReusableView.h"
@implementation LYWCollectionReusableView
- (instancetype)initWithFrame:(CGRect)frame{
if (self == [super initWithFrame:frame]) {
_dateLable = [[UILabel alloc]initWithFrame:self.bounds];
[_dateLable setTextAlignment:NSTextAlignmentCenter];
[_dateLable setFont:[UIFont systemFontOfSize:20]];
_dateLable.textColor = [UIColor blackColor];
[self addSubview:_dateLable];
}
returnself;
}
@end