日歷.gif
首先談?wù)劷M成
整體是個(gè)CollectionView杂彭,每個(gè)月就是一個(gè)section,XXXX年XX月和周一到周日部分是每個(gè)分組的Header视事,每個(gè)分組其實(shí)有42個(gè)Item匈勋,如果是當(dāng)月的Item顯示號(hào)數(shù)和副標(biāo)題礼旅,如果不是當(dāng)月的Item顯示空字符串并且隱藏當(dāng)天的副標(biāo)題
接下來是實(shí)現(xiàn)
5BD21078-8845-4698-BCB7-57D3655C2128.png
第一步 創(chuàng)建CalendarDateModel繼承自NSObject
#import <Foundation/Foundation.h>
@interface CalendarDateModel : NSObject
@property (nonatomic, copy)NSString *day;//當(dāng)天的號(hào)數(shù) 如果非當(dāng)月為空字符串
@property (nonatomic, assign)BOOL isPast;//用于在第一個(gè)月判斷是否是過的天數(shù)
//可以根據(jù)需求添加需要的屬性 這個(gè)model就是存儲(chǔ)在Item上需要顯示的信息
@end
第二步 創(chuàng)建CalendarDateManager 該類用于管理數(shù)據(jù)源 如果有網(wǎng)絡(luò)請(qǐng)求可以加在這里
.h
#import <Foundation/Foundation.h>
#import "CalendarDateModel.h"
@interface CalendarDateManager : NSObject
- (NSArray *)getDateArray;
@end
.m
#import "CalendarDateManager.h"
@interface CalendarDateManager (){
NSMutableArray *_dateArray;
}
@property (nonatomic, strong)NSDateFormatter *formatter;
@end
@implementation CalendarDateManager
- (instancetype)init
{
self = [super init];
if (self) {
[self initDateArray];
}
return self;
}
- (NSArray *)getDateArray{
return _dateArray.copy;
}
- (void)initDateArray{
NSDate *date = [NSDate new];//獲取當(dāng)前時(shí)間
NSInteger toDay = [self day:date];//獲取當(dāng)天是幾號(hào)
_dateArray = [NSMutableArray arrayWithCapacity:6];//這里寫死了一次創(chuàng)建6個(gè)月 可以根據(jù)需要改變 或者可以寫一個(gè)傳創(chuàng)建幾個(gè)月參數(shù)的初始化函數(shù)
for (int i = 0; i < 6; i++) { //循環(huán)6次 (6個(gè)月)
NSMutableArray *tmpArray = [NSMutableArray arrayWithCapacity:42];
NSInteger daysInThisMonth = [self totaldaysInThisMonth:date];
NSInteger firstWeekday = [self firstWeekdayInThisMonth:date];
for (NSInteger day = 0; day < 43; day++) {
CalendarDateModel *model = [CalendarDateModel new];
if (day < firstWeekday) {
model.day = @"";
}else if (day > firstWeekday + daysInThisMonth - 1){
model.day = @"";
}else{
if (i == 0) {//只判斷第一個(gè)月的天數(shù)是否是過去 后面幾個(gè)月沒必要判斷
if (day - firstWeekday + 1 < toDay) {
model.isPast = YES;
}//else不用判斷 默認(rèn)NO
}
model.day = [NSString stringWithFormat:@"%ld", day - firstWeekday + 1];
}
[tmpArray addObject:model];
}
NSDictionary *dic = @{@"date":[self.formatter stringFromDate:date], @"itemList":tmpArray};
[_dateArray addObject:dic];
date = [self nextMonth:date];
}
}
- (NSDateFormatter *)formatter{
if (!_formatter) {
_formatter = [[NSDateFormatter alloc] init];
_formatter.locale = [NSLocale localeWithLocaleIdentifier:@"zh_CN"];
[_formatter setDateFormat:@"yyyy-MM"];
}
return _formatter;
}
#pragma mark- 返回下個(gè)月的date
- (NSDate*)nextMonth:(NSDate *)date{
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
dateComponents.month = +1;
NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];
return newDate;
}
#pragma mark- 返回明天的date
- (NSDate*)nextDay:(NSDate *)date{
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
dateComponents.day = +1;
NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponents toDate:date options:0];
return newDate;
}
#pragma mark- 獲取當(dāng)前時(shí)間是幾號(hào)
- (NSInteger)day:(NSDate *)date{
NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date];
return [components day];
}
#pragma mark- 獲取當(dāng)月第一天的星期數(shù)
- (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;
}
#pragma mark- 獲取當(dāng)月天數(shù)
- (NSInteger)totaldaysInThisMonth:(NSDate *)date{
NSRange totaldaysInMonth = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
return totaldaysInMonth.length;
}
@end
第三步 自定義CollectionViewCell 和UICollectionReusableView
CalendarDateItem.h
#import <UIKit/UIKit.h>
@class CalendarDateModel;
@interface CalendarDateItem : UICollectionViewCell
- (void)setModel:(CalendarDateModel *)model;
@end
.m
#import "CalendarDateItem.h"
#import "CalendarDateModel.h"
#define COLOFOR0X(c) [UIColor colorWithRed:((c>>16)&0xFF)/255.0 \
green:((c>>8)&0xFF)/255.0 \
blue:(c&0xFF)/255.0 \
alpha:1.0]
#define COLORMAINBLUE COLOFOR0X(0x00b7f3)
@interface CalendarDateItem ()
@property (weak, nonatomic) IBOutlet UILabel *dayLabel;
@property (weak, nonatomic) IBOutlet UILabel *priceLabel;
@end
@implementation CalendarDateItem
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setModel:(CalendarDateModel *)model{
_dayLabel.text = model.day;
if ([_dayLabel.text isEqualToString:@""]) {
_priceLabel.hidden = YES;
}else{
if (model.isPast) {
_dayLabel.textColor = COLOFOR0X(0xbfbfbf);
_priceLabel.hidden = YES;
}else{
_dayLabel.textColor = COLORMAINBLUE;
_priceLabel.hidden = NO;
}
}
}
@end
image.png
CalendarMonthHeaderView.h
#import <UIKit/UIKit.h>
@interface CalendarMonthHeaderView : UICollectionReusableView
- (void)setDateString:(NSString *)date;
@end
.m
#import "CalendarMonthHeaderView.h"
@interface CalendarMonthHeaderView ()
@property (weak, nonatomic) IBOutlet UILabel *dateLabel;
@end
@implementation CalendarMonthHeaderView
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setDateString:(NSString *)date{
NSArray *array = [date componentsSeparatedByString:@"-"];
_dateLabel.text = [NSString stringWithFormat:@"%@ 年 %@ 月", array[0], array[1]];
}
@end
第四步 實(shí)現(xiàn)效果
#import "CalendarController.h"
#import "CalendarDateItem.h"
#import "CalendarMonthHeaderView.h"
#import "CalendarDateManager.h"
#define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
@interface CalendarController ()<UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>
@property (weak, nonatomic) IBOutlet UICollectionView *selectLiveTimeCollectionView;
@property (nonatomic, copy) NSArray *dateDataArray;
@end
@implementation CalendarController
- (void)viewDidLoad {
[super viewDidLoad];
UINib *nib = [UINib nibWithNibName:@"CalendarDateItem" bundle:nil];
[_selectLiveTimeCollectionView registerNib:nib forCellWithReuseIdentifier:@"CalendarDateItem"];
[_selectLiveTimeCollectionView registerNib:[UINib nibWithNibName:@"CalendarMonthHeaderView" bundle:nil]
forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CalendarMonthHeaderView"];
}
- (NSArray *)dateDataArray{
if (!_dateDataArray) {
_dateDataArray = [[[CalendarDateManager alloc] init] getDateArray];
}
return _dateDataArray;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return self.dateDataArray.count;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 42;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CalendarDateItem *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CalendarDateItem" forIndexPath:indexPath];
NSDictionary *dic = _dateDataArray[indexPath.section];
NSArray *tmpArray = dic[@"itemList"];
[cell setModel:tmpArray[indexPath.row]];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(SCREEN_WIDTH / 7.0, 45);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(0, 0, 0, 0);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
return 0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
return 0;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
if (kind == UICollectionElementKindSectionHeader) {
CalendarMonthHeaderView *headerRV = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"CalendarMonthHeaderView" forIndexPath:indexPath];
NSDictionary *dic = _dateDataArray[indexPath.section];
[headerRV setDateString:dic[@"date"]];
return headerRV;
}else{
return nil;
}
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
return CGSizeMake(SCREEN_WIDTH, 111);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{
return CGSizeMake(0, 0);
}
@end