diff --git a/ALCalendarPicker/ALCalendarCell.h b/ALCalendarPicker/ALCalendarCell.h new file mode 100644 index 0000000..353f9f6 --- /dev/null +++ b/ALCalendarPicker/ALCalendarCell.h @@ -0,0 +1,22 @@ +// +// ALCalendarCell.h +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/16. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import + +@class ALCalendarDate; + +@interface ALCalendarCell : UICollectionViewCell + +@property (nonatomic, strong) ALCalendarDate *date; + +/** 星期 */ +@property (nonatomic, copy) NSString *weekDay; + +@property (nonatomic, strong, readonly) UILabel *dateLabel; + +@end diff --git a/ALCalendarPicker/ALCalendarCell.m b/ALCalendarPicker/ALCalendarCell.m new file mode 100644 index 0000000..b7a18c2 --- /dev/null +++ b/ALCalendarPicker/ALCalendarCell.m @@ -0,0 +1,79 @@ +// +// ALCalendarCell.m +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/16. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import "ALCalendarCell.h" + +#import "ALCalendarDate.h" + +#import + +#define KLightGrayColor [UIColor colorWithRed:127.0/255.0 green:143.0/255.0 blue:164.0/255.0 alpha:1] + +#define KDarkGrayColor [UIColor colorWithRed:44.0/255.0 green:49.0/255.0 blue:53.0/255.0 alpha:1] + +@interface ALCalendarCell() + +@property (nonatomic, strong) UILabel *dateLabel; + +@end + +@implementation ALCalendarCell + +- (instancetype)initWithFrame:(CGRect)frame +{ + if(self = [super initWithFrame:frame]) { + [self setupView]; + } + return self; +} + +- (void)setupView +{ + [self addSubview:self.dateLabel]; + + self.layer.cornerRadius = 5.0f; + + __weak typeof(self) weakSelf = self; + [self.dateLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(weakSelf.mas_centerX); + make.centerY.equalTo(weakSelf.mas_centerY); + }]; +} + +- (void)setDate:(ALCalendarDate *)date +{ + _date = date; + if (date.notThisMonth) { + self.backgroundColor = [UIColor whiteColor]; + self.dateLabel.textColor = KLightGrayColor; + } else { + self.backgroundColor = [UIColor whiteColor]; + self.dateLabel.textColor = KDarkGrayColor; + } + self.dateLabel.text = date.date; +} + +- (void)setWeekDay:(NSString *)weekDay +{ + _weekDay = weekDay; + self.dateLabel.text = weekDay; + self.dateLabel.textColor = KLightGrayColor; +} + +- (UILabel *)dateLabel +{ + if (!_dateLabel) { + _dateLabel = [[UILabel alloc] init]; + _dateLabel.textColor = KDarkGrayColor; + _dateLabel.font = [UIFont systemFontOfSize:14]; + } + return _dateLabel; +} + + +@end diff --git a/ALCalendarPicker/ALCalendarCollectionView.h b/ALCalendarPicker/ALCalendarCollectionView.h new file mode 100644 index 0000000..69b3b76 --- /dev/null +++ b/ALCalendarPicker/ALCalendarCollectionView.h @@ -0,0 +1,33 @@ +// +// ALCalendarCollectionView.h +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/16. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import + +@class ALCalendarDate,ALCalendarCollectionView,ALCalendarConfig; + +@protocol ALCalendarCollectionViewDelegate + +/** + * 点击了某个日期 + */ +- (void)calendarView:(ALCalendarCollectionView *)calendarCollectionView didSelectItem:(ALCalendarDate *)date dateString:(NSString *)dateString; + +@end + +@interface ALCalendarCollectionView : UICollectionView + +/** 当前的年份和月份 yyyy-MM */ +@property (nonatomic, copy) NSString *yearAndMonth; + +/** 代理 */ +@property (nonatomic, assign) id collectionViewDelegate; + +/** 配置 */ +@property (nonatomic, strong) ALCalendarConfig *config; + +@end diff --git a/ALCalendarPicker/ALCalendarCollectionView.m b/ALCalendarPicker/ALCalendarCollectionView.m new file mode 100644 index 0000000..9c1b8e0 --- /dev/null +++ b/ALCalendarPicker/ALCalendarCollectionView.m @@ -0,0 +1,133 @@ +// +// ALCalendarCollectionView.m +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/16. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import "ALCalendarCollectionView.h" + +#import "ALCalendarCell.h" + +#import "ALCalendarDate.h" +#import "ALCalendarHelper.h" +#import "ALCalendarConfig.h" + +#import "UIView+Frame.h" + +@interface ALCalendarCollectionView() + +@property (nonatomic, strong) NSArray *titles; + +@property (nonatomic, strong) NSArray *dates; + +@end + +@implementation ALCalendarCollectionView + +static NSString *identifier = @"dateCell"; + +- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(nonnull UICollectionViewLayout *)layout +{ + if (self = [super initWithFrame:frame collectionViewLayout:layout]) { + self.dataSource = self; + self.delegate = self; + self.contentInset = UIEdgeInsetsMake(5, 20, 0, 20); + self.backgroundColor = [UIColor whiteColor]; + [self registerClass:[ALCalendarCell class] forCellWithReuseIdentifier:identifier]; + } + return self; +} + +#pragma mark - UICollectionDataSource +- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView +{ + return 2; +} + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + if (section == 0) return 7; + return self.dates.count; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + ALCalendarCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; + cell.backgroundColor = [UIColor whiteColor]; + + if(indexPath.section == 0) { + cell.weekDay = self.titles[indexPath.row]; + } else { + ALCalendarDate *date = self.dates[indexPath.row]; + cell.date = date; + + /** 当前显示的日期 */ + NSString *currentDate = [self.yearAndMonth stringByAppendingFormat:@"-%02zd",date.date.integerValue]; + + if ([self.config.heightlightDates containsObject:currentDate]) { + cell.backgroundColor = self.config.hl_backgroundColor; + cell.layer.cornerRadius = self.config.hl_backgroundCornerRadius.floatValue; + cell.dateLabel.textColor = self.config.hl_textColor; + } + + if (date.isToday) { + if (![self.config.heightlightDates containsObject:currentDate] || + ([self.config.heightlightDates containsObject:currentDate] && !self.config.hightlightPriority)) { + cell.backgroundColor = self.config.tod_backgroundColor; + cell.layer.cornerRadius = self.config.tod_backgroundCornerRadius.floatValue; + cell.dateLabel.textColor = self.config.tod_textColor; + } + } + } + return cell; +} + +#pragma mark - UICollectionDelegate + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + if ([self.collectionViewDelegate respondsToSelector:@selector(calendarView:didSelectItem:dateString:)]) { + ALCalendarDate *date = self.dates[indexPath.row]; + [self.collectionViewDelegate calendarView:self didSelectItem:date dateString:[self.yearAndMonth stringByAppendingFormat:@"-%02zd",date.date.integerValue]]; + } +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath +{ + return CGSizeMake(self.width / 10, self.width / 10); +} + +- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section +{ + return 10; +} + +- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section +{ + return 10; +} + +- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section +{ + return UIEdgeInsetsMake(5, 0, 5, 0); +} + +#pragma mark - setter & getter + +- (NSArray *)titles +{ + return @[@"日",@"一",@"二",@"三",@"四",@"五",@"六"]; +} + +- (void)setYearAndMonth:(NSString *)yearAndMonth +{ + _yearAndMonth = yearAndMonth; + if (yearAndMonth) { + _dates = [ALCalendarHelper datesWithYearAndMonth:yearAndMonth]; + [self reloadData]; + } +} + +@end diff --git a/ALCalendarPicker/ALCalendarConfig.h b/ALCalendarPicker/ALCalendarConfig.h new file mode 100644 index 0000000..5aa3e3e --- /dev/null +++ b/ALCalendarPicker/ALCalendarConfig.h @@ -0,0 +1,41 @@ +// +// ALCalendarConfig.h +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/17. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import + +@interface ALCalendarConfig : NSObject + +/** 当前日期优先 */ +@property (nonatomic, assign) BOOL hightlightPriority; + +/**** 今天日期 *****/ + +/** 文字颜色 */ +@property (nonatomic, strong) UIColor *tod_textColor; + +/** 背景颜色 */ +@property (nonatomic, strong) UIColor *tod_backgroundColor; + +/** 圆角 */ +@property (nonatomic, strong) NSNumber *tod_backgroundCornerRadius; + +/**** 高亮日期 ****/ + +/** 高亮日期 */ +@property (nonatomic, strong) NSArray *heightlightDates; + +/** 文字颜色 */ +@property (nonatomic, strong) UIColor *hl_textColor; + +/** 背景颜色 */ +@property (nonatomic, strong) UIColor *hl_backgroundColor; + +/** 圆角 */ +@property (nonatomic, strong) NSNumber *hl_backgroundCornerRadius; + +@end diff --git a/ALCalendarPicker/ALCalendarConfig.m b/ALCalendarPicker/ALCalendarConfig.m new file mode 100644 index 0000000..69d77fd --- /dev/null +++ b/ALCalendarPicker/ALCalendarConfig.m @@ -0,0 +1,13 @@ +// +// ALCalendarConfig.m +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/17. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import "ALCalendarConfig.h" + +@implementation ALCalendarConfig + +@end diff --git a/ALCalendarPicker/ALCalendarDate.h b/ALCalendarPicker/ALCalendarDate.h new file mode 100644 index 0000000..f0de5d1 --- /dev/null +++ b/ALCalendarPicker/ALCalendarDate.h @@ -0,0 +1,24 @@ +// +// ALCalendarDate.h +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/17. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import + +@interface ALCalendarDate : NSObject + +/** 日期(号数) */ +@property (nonatomic, copy) NSString *date; + +/** 不是这个月 */ +@property (nonatomic, assign) BOOL notThisMonth; + +/** 是今天 */ +@property (nonatomic, assign) BOOL isToday; + ++ (instancetype)dateWith:(NSString *)dateStr isNotThisMonth:(BOOL)notThisMonth; + +@end diff --git a/ALCalendarPicker/ALCalendarDate.m b/ALCalendarPicker/ALCalendarDate.m new file mode 100644 index 0000000..13200e5 --- /dev/null +++ b/ALCalendarPicker/ALCalendarDate.m @@ -0,0 +1,21 @@ +// +// ALCalendarDate.m +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/17. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import "ALCalendarDate.h" + +@implementation ALCalendarDate + ++ (instancetype)dateWith:(NSString *)dateStr isNotThisMonth:(BOOL)notThisMonth +{ + ALCalendarDate *date = [[ALCalendarDate alloc] init]; + date.date = dateStr; + date.notThisMonth = notThisMonth; + return date; +} + +@end diff --git a/ALCalendarPicker/ALCalendarHeader.h b/ALCalendarPicker/ALCalendarHeader.h new file mode 100644 index 0000000..516d727 --- /dev/null +++ b/ALCalendarPicker/ALCalendarHeader.h @@ -0,0 +1,38 @@ +// +// ALCalendarHeader.h +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/16. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import + +@class ALCalendarHeader; + +@protocol ALCalendarHeaderDelegate + +/** + 点击了左边的按钮 + */ +- (void)header:(ALCalendarHeader *)header didClickLeftBtn:(UIButton *)button; + +/** + 点击了右边的按钮 + */ +- (void)header:(ALCalendarHeader *)header didClickRightBtn:(UIButton *)button; + +@end + +@interface ALCalendarHeader : UIView + +@property (nonatomic, copy) NSString *title; + +/** 起始年月 yyyy-MM */ +@property (nonatomic, copy) NSString *beginYearMonth; + +/** 代理 */ +@property (nonatomic, assign) id delegate; + + +@end diff --git a/ALCalendarPicker/ALCalendarHeader.m b/ALCalendarPicker/ALCalendarHeader.m new file mode 100644 index 0000000..1a8f058 --- /dev/null +++ b/ALCalendarPicker/ALCalendarHeader.m @@ -0,0 +1,136 @@ +// +// ALCalendarHeader.m +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/16. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import "ALCalendarHeader.h" + +#import "ALCalendarHelper.h" + +#import "UIView+Frame.h" + +#import + +@interface ALCalendarHeader() + +@property (nonatomic, strong) UIButton *leftBtn; + +@property (nonatomic, strong) UIButton *rightBtn; + +@property (nonatomic, strong) UILabel *titleLabel; + +@end + +@implementation ALCalendarHeader + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + [self setupView]; + } + return self; +} + +- (void)setupView +{ + [self addSubview: self.leftBtn]; + [self addSubview: self.titleLabel]; + [self addSubview: self.rightBtn]; + + __weak typeof(self) weakSelf = self; + + [self.leftBtn mas_makeConstraints:^(MASConstraintMaker *make) { + __strong typeof(weakSelf) strongSelf = weakSelf; + make.left.equalTo(@15); + make.centerY.equalTo(strongSelf.mas_centerY); + make.height.equalTo(@15); + make.width.equalTo(@15); + }]; + + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + __strong typeof(weakSelf) strongSelf = weakSelf; + make.centerX.equalTo(strongSelf.mas_centerX); + make.centerY.equalTo(strongSelf.mas_centerY); + }]; + + [self.rightBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.trailing.equalTo(@-15); + make.centerY.equalTo(weakSelf.mas_centerY); + make.height.equalTo(@15); + make.width.equalTo(@15); + }]; +} + +- (void)leftBtnDidClicked:(UIButton *)button +{ + if ([self.delegate respondsToSelector:@selector(header:didClickLeftBtn:)]) { + [self.delegate header:self didClickLeftBtn:button]; + } +} + +- (void)rightBtnDidClicked:(UIButton *)button +{ + if ([self.delegate respondsToSelector:@selector(header:didClickRightBtn:)]) { + [self.delegate header:self didClickRightBtn:button]; + } +} + + +- (UIImage *)imagesNamedFromCustomBundle:(NSString *)imgName +{ + NSString *bundlePath = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:@"ALCalendarPicker.bundle"]; + NSBundle *bundle = [NSBundle bundleWithPath:bundlePath]; + NSString *img_path = [bundle pathForResource:imgName ofType:@"png"]; + return [UIImage imageWithContentsOfFile:img_path]; +} + +#pragma mark - setter & getter + +- (UIButton *)leftBtn +{ + if (!_leftBtn) { + _leftBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + [_leftBtn setImage: [self imagesNamedFromCustomBundle:@"ic_lastday"] forState:UIControlStateNormal]; + [_leftBtn addTarget:self action:@selector(leftBtnDidClicked:) forControlEvents:UIControlEventTouchUpInside]; + } + return _leftBtn; +} + +- (UIButton *)rightBtn +{ + if (!_rightBtn) { + _rightBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + [_rightBtn setImage: [self imagesNamedFromCustomBundle:@"ic_nextday"] forState:UIControlStateNormal]; + [_rightBtn addTarget:self action:@selector(rightBtnDidClicked:) forControlEvents:UIControlEventTouchUpInside]; + } + return _rightBtn; +} + +- (UILabel *)titleLabel +{ + if (!_titleLabel) { + _titleLabel = [[UILabel alloc] init]; + _titleLabel.font = [UIFont systemFontOfSize:16]; + _titleLabel.textColor = [UIColor darkGrayColor]; + } + return _titleLabel; +} + +- (void)setTitle:(NSString *)title +{ + _title = title; + // 格式化显示日期 + NSArray *dates = [title componentsSeparatedByString:@"-"]; + self.titleLabel.text = [NSString stringWithFormat:@"%@年 - %@月",dates.firstObject,dates.lastObject]; + + if([title isEqualToString:self.beginYearMonth]) { + self.leftBtn.enabled = NO; + } else { + self.leftBtn.enabled = YES; + } +} + +@end diff --git a/ALCalendarPicker/ALCalendarHelper.h b/ALCalendarPicker/ALCalendarHelper.h new file mode 100644 index 0000000..3af7ddf --- /dev/null +++ b/ALCalendarPicker/ALCalendarHelper.h @@ -0,0 +1,28 @@ +// +// ALCalendarHelper.h +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/16. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import + +@interface ALCalendarHelper : NSObject + +/** 根据当前年月得出日历数组 */ ++ (NSArray *)datesWithYearAndMonth:(NSString *)ym; + +/** 当前的年份和月份 yyyy-MM */ ++ (NSString *)currentYearAndMonth; + +/** 今天 yyyy-MM-dd */ ++ (NSString *)today; + +/** 指定某个年月yyyy-MM 得到下个年月yyyy-MM */ ++ (NSString *)nextYearAndMonth:(NSString *)thisYearAndMonth; + +/** 指定某个年月yyyy-MM 得到上个年月yyyy-MM */ ++ (NSString *)lastYearAndMonth:(NSString *)thisYearAndMonth; + +@end diff --git a/ALCalendarPicker/ALCalendarHelper.m b/ALCalendarPicker/ALCalendarHelper.m new file mode 100644 index 0000000..926da68 --- /dev/null +++ b/ALCalendarPicker/ALCalendarHelper.m @@ -0,0 +1,142 @@ +// +// ALCalendarHelper.m +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/16. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import "ALCalendarHelper.h" +#import "ALCalendarDate.h" + +@implementation ALCalendarHelper + ++ (NSArray *)datesWithYearAndMonth:(NSString *)ym +{ + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; + + // 设定一号 + NSString *dateStr = [ym stringByAppendingString:@"-01"]; + + // 转成NSDate + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; + formatter.dateFormat = @"yyyy-MM-dd"; + + NSDate *date = [self dateStringToDate:dateStr format:@"yyyy-MM-dd"]; + + // 转成日历组件 + NSDateComponents *comps; + comps = [calendar components:unitFlags fromDate:date]; + + // 当前月一号是星期几(注意,周日是“1”,周一是“2”。。。。) + NSInteger weekday = comps.weekday; + // 当前月的天数 + NSInteger days = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date].length; + // 当前月最后一天 + NSString *thisMonthLastDateStr = [NSString stringWithFormat:@"%@-%zd",ym,days]; + NSDate *thisMonthLastDate = [formatter dateFromString:thisMonthLastDateStr]; + // 当前月最后一天是星期几 + comps = [calendar components:unitFlags fromDate:thisMonthLastDate]; + NSInteger lastDaysWeekDay = comps.weekday; + + // 上个月的天数 + [comps setDay:1]; + [comps setMonth:comps.month - 1]; + NSDate *lastMonth = [calendar dateFromComponents:comps]; + NSInteger lastMonthDays = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:lastMonth].length; + + NSMutableArray *lastMonthDates = [NSMutableArray array]; + for (NSInteger i = 0; i < weekday - 1; i++) { + NSString *d = [NSString stringWithFormat:@"%zd",lastMonthDays - i]; + ALCalendarDate *dat = [ALCalendarDate dateWith:d isNotThisMonth:YES]; + [lastMonthDates addObject:dat]; + } + lastMonthDates = [lastMonthDates reverseObjectEnumerator].allObjects.mutableCopy; + + NSMutableArray *thisMonthDates = [NSMutableArray array]; + for (NSInteger i = 1 ; i <= days ; i++) { + NSString *d = [NSString stringWithFormat:@"%zd",i]; + ALCalendarDate *dat = [ALCalendarDate dateWith:d isNotThisMonth:NO]; + if ([[ym stringByAppendingFormat:@"-%@",d] isEqualToString:[self today]]) { // 判断今天 + dat.isToday = YES; + } + [thisMonthDates addObject:dat]; + } + + NSMutableArray *nextMonthDates = [NSMutableArray array]; + for (NSInteger i = 1 ; i <= 7 - lastDaysWeekDay; i++) { + NSString *d = [NSString stringWithFormat:@"%zd",i]; + ALCalendarDate *dat = [ALCalendarDate dateWith:d isNotThisMonth:YES]; + [nextMonthDates addObject:dat]; + } + + NSMutableArray *arr = [NSMutableArray arrayWithArray:lastMonthDates]; + [arr addObjectsFromArray:thisMonthDates]; + [arr addObjectsFromArray:nextMonthDates]; + + return arr; +} + ++ (NSString *)currentYearAndMonth +{ + NSDate *now = [NSDate date]; + + // 转成NSDate + NSString *dateStr = [self dateToDateString:now format:@"yyyy-MM"]; + + return dateStr; +} + ++ (NSString *)today +{ + NSString *todayDate = [self dateToDateString:[NSDate date] format:@"yyyy-MM-dd"]; + return todayDate; +} + ++ (NSString *)nextYearAndMonth:(NSString *)thisYearAndMonth +{ + NSDate *date = [self dateStringToDate:thisYearAndMonth format:@"yyyy-MM"]; + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth; + NSDateComponents *comps = [calendar components:unitFlags fromDate:date]; + comps.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; + [comps setMonth: comps.month + 1]; + NSDate *nextMonth = [calendar dateFromComponents:comps]; + return [self dateToDateString:nextMonth format:@"yyyy-MM"]; +} + ++ (NSString *)lastYearAndMonth:(NSString *)thisYearAndMonth +{ + NSDate *date = [self dateStringToDate:thisYearAndMonth format:@"yyyy-MM"]; + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth; + NSDateComponents *comps = [calendar components:unitFlags fromDate:date]; + comps.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; + [comps setMonth: comps.month - 1]; + NSDate *lastMonth = [calendar dateFromComponents:comps]; + return [self dateToDateString:lastMonth format:@"yyyy-MM"]; +} + ++ (NSString *)dateToDateString:(NSDate *)date format:(NSString *)format +{ + // 转成NSDate + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; + formatter.dateFormat = format; + NSString *dateStr = [formatter stringFromDate:date]; + return dateStr; +} + ++ (NSDate *)dateStringToDate:(NSString *)dateString format:(NSString *)format +{ + // 转成NSDate + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; + formatter.dateFormat = format; + NSDate *date = [formatter dateFromString:dateString]; + return date; +} + +@end diff --git a/ALCalendarPicker/ALCalendarPicker.bundle/ic_lastday.png b/ALCalendarPicker/ALCalendarPicker.bundle/ic_lastday.png new file mode 100644 index 0000000..9d0286f Binary files /dev/null and b/ALCalendarPicker/ALCalendarPicker.bundle/ic_lastday.png differ diff --git a/ALCalendarPicker/ALCalendarPicker.bundle/ic_nextday.png b/ALCalendarPicker/ALCalendarPicker.bundle/ic_nextday.png new file mode 100644 index 0000000..a42a334 Binary files /dev/null and b/ALCalendarPicker/ALCalendarPicker.bundle/ic_nextday.png differ diff --git a/ALCalendarPicker/ALCalendarPicker.h b/ALCalendarPicker/ALCalendarPicker.h new file mode 100644 index 0000000..86091d7 --- /dev/null +++ b/ALCalendarPicker/ALCalendarPicker.h @@ -0,0 +1,41 @@ +// +// ALCalendarPicker.h +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/16. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import + +@class ALCalendarPicker,ALCalendarDate; + +@protocol ALCalendarPickerDelegate + +/** + 选择某个日期 + */ +- (void)calendarPicker:(ALCalendarPicker *)picker didSelectItem:(ALCalendarDate *)date dateString:(NSString *)dateStr; + +@end + +@interface ALCalendarPicker : UIView + +/** 起始年月 yyyy-MM */ +@property (nonatomic, copy) NSString *beginYearMonth; + +@property (nonatomic, assign) id delegate; + +/** 高亮日期 yyyy-MM-dd 格式 */ +@property (nonatomic, assign) NSArray *hightLightItems; + +/** 高亮日期优先 当高亮日期与当日日期的重叠的时候优先使用高亮日期的样式 */ +@property (nonatomic, assign) BOOL hightlightPriority; + +/** 高亮的日期的样式 */ +- (void)setupHightLightItemStyle:(void(^)(UIColor **backgroundColor,NSNumber **backgroundCornerRadius,UIColor **titleColor))style; + +/** 当日日期的样式 */ +- (void)setupTodayItemStyle:(void(^)(UIColor **backgroundColor,NSNumber **backgroundCornerRadius,UIColor **titleColor))style; + +@end diff --git a/ALCalendarPicker/ALCalendarPicker.m b/ALCalendarPicker/ALCalendarPicker.m new file mode 100644 index 0000000..3aa2ea4 --- /dev/null +++ b/ALCalendarPicker/ALCalendarPicker.m @@ -0,0 +1,267 @@ +// +// ALCalendarPicker.m +// ALCalendarPickerDemo +// +// Created by Arclin on 2017/6/16. +// Copyright © 2017年 arclin. All rights reserved. +// + +#import "ALCalendarPicker.h" + +#import "ALCalendarHeader.h" +#import "ALCalendarCollectionView.h" + +#import "ALCalendarHelper.h" +#import "ALCalendarConfig.h" + +#import "UIView+Frame.h" + +#import + +@interface ALCalendarPicker() +{ + NSInteger _currentPage; +} +@property (nonatomic, strong) ALCalendarHeader * header; + +@property (nonatomic, strong) UIScrollView * scrollView; + +@property (nonatomic, strong) NSMutableArray *collectionViews; + +/** 配置 */ +@property (nonatomic, strong) ALCalendarConfig *config; + +@end + +@implementation ALCalendarPicker + +static CGFloat headerHeight = 45; + +- (instancetype)initWithFrame:(CGRect)frame +{ + if(self = [super initWithFrame:frame]) + { + [self setupView]; + } + return self; +} + +- (void)setupView +{ + [self addSubview: self.header]; + [self addSubview: self.scrollView]; + + __weak typeof(self) weakSelf = self; + + // 头部信息栏 + [self.header mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(@0); + make.top.equalTo(@0); + make.width.equalTo(weakSelf.mas_width); + make.height.equalTo(@(headerHeight)); + }]; + + // 内容 + [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) { + __strong typeof(weakSelf) strongSelf = weakSelf; + make.left.equalTo(@0); + make.top.equalTo(strongSelf.header.mas_bottom); + make.bottom.equalTo(@0); + make.right.equalTo(@0); + }]; +} + +- (void)setupTodayItemStyle:(void(^)(UIColor **backgroundColor,NSNumber **backgroundCornerRadius,UIColor **titleColor))style +{ + UIColor *backgroundColor; + UIColor *titleColor; + NSNumber *backgroundCornerRadius; + if (style) { + style(&backgroundColor,&backgroundCornerRadius,&titleColor); + } + // 配置今日日期样式 + self.config.tod_backgroundColor = backgroundColor; + self.config.tod_textColor = titleColor; + self.config.tod_backgroundCornerRadius = backgroundCornerRadius; + + for (ALCalendarCollectionView *collectionView in self.collectionViews) { + collectionView.config = self.config; + [collectionView reloadData]; + } +} + +- (void)setupHightLightItemStyle:(void(^)(UIColor **backgroundColor,NSNumber **backgroundCornerRadius,UIColor **titleColor))style +{ + UIColor *backgroundColor; + UIColor *titleColor; + NSNumber *backgroundCornerRadius; + if (style) { + style(&backgroundColor,&backgroundCornerRadius,&titleColor); + } + // 配置高亮样式 + self.config.hl_backgroundColor = backgroundColor; + self.config.hl_textColor = titleColor; + self.config.hl_backgroundCornerRadius = backgroundCornerRadius; + + for (ALCalendarCollectionView *collectionView in self.collectionViews) { + collectionView.config = self.config; + [collectionView reloadData]; + } +} + +#pragma mark - Private Method + +- (void)showLeftCalendar +{ + self.header.title = [ALCalendarHelper lastYearAndMonth:self.header.title]; + [self refreshCollectionView:NO]; +} + +- (void)showRightCalendar +{ + self.header.title = [ALCalendarHelper nextYearAndMonth:self.header.title]; + [self refreshCollectionView:YES]; +} + +- (void)setupLeftAndRightCalendar +{ + // 配置上个月和下个月的数据源 + self.collectionViews.firstObject.yearAndMonth = [ALCalendarHelper lastYearAndMonth:self.header.title]; + self.collectionViews.lastObject.yearAndMonth = [ALCalendarHelper nextYearAndMonth:self.header.title]; +} + +#pragma mark - UIScrollViewDelegate + +- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView +{ + [self.scrollView setContentOffset:CGPointMake(self.width, 0) animated:NO]; + + [self setupLeftAndRightCalendar]; +} + +- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView +{ + CGFloat offsetX = scrollView.contentOffset.x; + CGFloat page = offsetX / self.width; + if (page == 2) { + [self showRightCalendar]; + } else if (page == 0) { + [self showLeftCalendar]; + } + + [self.scrollView setContentOffset:CGPointMake(self.width, 0) animated:NO]; + + // 配置上个月和下个月的数据源 + [self setupLeftAndRightCalendar]; +} + +#pragma mark - ALCalendarHeaderDelegate + +- (void)header:(ALCalendarHeader *)header didClickLeftBtn:(UIButton *)button +{ + [self showLeftCalendar]; +} + +- (void)header:(ALCalendarHeader *)header didClickRightBtn:(UIButton *)button +{ + [self showRightCalendar]; +} + +#pragma mark - ALCalendarCollectionViewDelegate + +- (void)calendarView:(ALCalendarCollectionView *)calendarCollectionView didSelectItem:(ALCalendarDate *)date dateString:(NSString *)dateString +{ + if ([self.delegate respondsToSelector:@selector(calendarPicker:didSelectItem:dateString:)]) { + [self.delegate calendarPicker:self didSelectItem:date dateString:dateString]; + } +} + +#pragma mark - private method + +- (void)refreshCollectionView:(BOOL)next +{ + if (next) { // 滚到下一页 + [self.scrollView setContentOffset:CGPointMake(2 * self.width , 0) animated:YES]; + } else { // 滚到上一页 + [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES]; + } + self.collectionViews[1].yearAndMonth = self.header.title; +} + +#pragma mark - setter & getter + +- (ALCalendarHeader *)header +{ + if (!_header) { + _header = [[ALCalendarHeader alloc] init]; + // 初始化为当前月份和年份 + _header.title = [ALCalendarHelper currentYearAndMonth]; + _header.delegate = self; + } + return _header; +} + +- (void)setBeginYearMonth:(NSString *)beginYearMonth +{ + _beginYearMonth = beginYearMonth; + self.header.beginYearMonth = beginYearMonth; +} + +- (UIScrollView *)scrollView +{ + if (!_scrollView) { + _scrollView = [[UIScrollView alloc] init]; + _scrollView.pagingEnabled = YES; + CGFloat height = self.height - headerHeight; + _scrollView.contentSize = (CGSize){self.width * 3,height}; + _scrollView.delegate = self; + for (NSInteger i = 0; i < 3 ; i++) { + ALCalendarCollectionView *collectionView = [[ALCalendarCollectionView alloc] initWithFrame:CGRectMake(self.width * i, 0, self.width,height) collectionViewLayout:[[UICollectionViewFlowLayout alloc] init]]; + collectionView.collectionViewDelegate = self; + collectionView.yearAndMonth = nil; + if (i == 0) { + collectionView.yearAndMonth = [ALCalendarHelper lastYearAndMonth:self.header.title]; + }else if (i == 1) { + collectionView.yearAndMonth = [ALCalendarHelper currentYearAndMonth]; + } else if (i == 2) { + collectionView.yearAndMonth = [ALCalendarHelper nextYearAndMonth:self.header.title]; + } + [self.collectionViews addObject:collectionView]; + [self.scrollView addSubview:collectionView]; + } + _scrollView.showsHorizontalScrollIndicator = NO; +// _scrollView.scrollEnabled = NO; + [_scrollView setContentOffset:CGPointMake(self.width, 0) animated:NO]; + } + return _scrollView; +} + +- (NSMutableArray *)collectionViews +{ + if (!_collectionViews) { + _collectionViews = [NSMutableArray array]; + } + return _collectionViews; +} + +- (void)setHightLightItems:(NSArray *)hightLightItems +{ + _hightLightItems = hightLightItems; + self.config.heightlightDates = hightLightItems; +} + +- (void)setHightlightPriority:(BOOL)hightlightPriority +{ + _hightlightPriority = hightlightPriority; + self.config.hightlightPriority = hightlightPriority; +} + +- (ALCalendarConfig *)config +{ + if (!_config) { + _config = [[ALCalendarConfig alloc] init]; + } + return _config; +} + +@end diff --git a/ALCalendarPicker/UIView+Frame.h b/ALCalendarPicker/UIView+Frame.h new file mode 100755 index 0000000..24f9067 --- /dev/null +++ b/ALCalendarPicker/UIView+Frame.h @@ -0,0 +1,24 @@ +// +// UIView+Frame.h +// ArcBlog +// +// Created by Arclin on 15/11/18. +// Copyright © 2015年 sziit. All rights reserved. +// + +#import + +@interface UIView (Frame) + +// 分类不能添加成员属性 +// @property如果在分类里面,只会自动生成get,set方法的声明,不会生成带有下划线的成员属性,和方法的实现 + +@property (nonatomic,assign) CGFloat centerX; +@property (nonatomic,assign) CGFloat centerY; +@property (nonatomic,assign) CGSize size; +@property (nonatomic,assign) CGFloat x; +@property (nonatomic,assign) CGFloat y; +@property (nonatomic,assign) CGFloat width; +@property (nonatomic,assign) CGFloat height; + +@end diff --git a/ALCalendarPicker/UIView+Frame.m b/ALCalendarPicker/UIView+Frame.m new file mode 100755 index 0000000..18024c5 --- /dev/null +++ b/ALCalendarPicker/UIView+Frame.m @@ -0,0 +1,85 @@ +// +// UIView+Frame.m +// ArcBlog +// +// Created by Arclin on 15/11/18. +// Copyright © 2015年 sziit. All rights reserved. +// + +#import "UIView+Frame.h" + +@implementation UIView (Frame) + +- (void)setCenterX:(CGFloat)centerX{ + CGPoint center = self.center; + center.x = centerX; + self.center = center; +} + +- (CGFloat)centerX{ + return self.center.x; +} + + +- (void)setCenterY:(CGFloat)centerY{ + CGPoint center = self.center; + center.y = centerY; + self.center = center; +} + +- (CGFloat)centerY{ + return self.center.y; +} + +- (void)setSize:(CGSize)size{ + CGRect frame = self.frame; + frame.size = size; + self.frame = frame; +} + +- (CGSize)size{ + return self.frame.size; +} + +- (void)setX:(CGFloat)x{ + CGRect frame = self.frame; + frame.origin.x = x; + self.frame = frame; +} + +- (CGFloat)x{ + return self.frame.origin.x; +} + +- (void)setY:(CGFloat)y{ + CGRect frame = self.frame; + frame.origin.y = y; + self.frame = frame; +} + +- (CGFloat)y{ + return self.frame.origin.y; + +} + +- (void)setWidth:(CGFloat)width{ + CGRect frame = self.frame; + frame.size.width = width; + self.frame = frame; +} + +- (CGFloat)width{ + return self.frame.size.width; +} + +- (void)setHeight:(CGFloat)height{ + CGRect frame = self.frame; + frame.size.height = height; + self.frame = frame; +} + +- (CGFloat)height{ + return self.frame.size.height; +} + +@end