iOS 簡(jiǎn)單日歷表

日歷.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
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市洽洁,隨后出現(xiàn)的幾起案子各淀,更是在濱河造成了極大的恐慌,老刑警劉巖诡挂,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碎浇,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡璃俗,警方通過查閱死者的電腦和手機(jī)刨疼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哮缺,“玉大人验辞,你說我怎么就攤上這事〕牵” “怎么了雳旅?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)间聊。 經(jīng)常有香客問我攒盈,道長(zhǎng),這世上最難降的妖魔是什么哎榴? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任型豁,我火速辦了婚禮,結(jié)果婚禮上尚蝌,老公的妹妹穿的比我還像新娘迎变。我一直安慰自己,他們只是感情好飘言,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布衣形。 她就那樣靜靜地躺著,像睡著了一般姿鸿。 火紅的嫁衣襯著肌膚如雪谆吴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天般妙,我揣著相機(jī)與錄音纪铺,去河邊找鬼。 笑死碟渺,一個(gè)胖子當(dāng)著我的面吹牛鲜锚,可吹牛的內(nèi)容都是我干的突诬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼芜繁,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼旺隙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起骏令,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蔬捷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后榔袋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體周拐,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年凰兑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妥粟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吏够,死狀恐怖勾给,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锅知,我是刑警寧澤播急,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站售睹,受9級(jí)特大地震影響桩警,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜侣姆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一生真、第九天 我趴在偏房一處隱蔽的房頂上張望沉噩。 院中可真熱鬧捺宗,春花似錦、人聲如沸川蒙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)畜眨。三九已至昼牛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間康聂,已是汗流浹背贰健。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恬汁,地道東北人伶椿。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親脊另。 傳聞我的和親對(duì)象是個(gè)殘疾皇子导狡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容