(一)前言服務器
項目中須要簽到功能,因此要運用到一個簡易日曆,原來老版本的日曆用戶體驗至關的很差,因此在這裏封裝一個簡易的日曆,關鍵的點就是:當前月的第一天是星期幾以及當前月有多少天,下面看代碼。佈局
(二)佈局;測試
(1)整個view分兩個部分,頂部爲一個顯示時間的topview,裏面在添加一個uilabel顯示時間;下部是一個UICollectionView,分爲兩個section,第一個section是顯示星期幾;第二個section顯示的當前月份的days;ui
(2)view裏面能夠加入數據交互,好比從後臺獲取信息並顯示;atom
#import "ZJCalendar.h" #import "ZJCalendarCell.h" static NSString * const ZJCalendarCellIdentifier = @"cell"; @interface ZJCalendar () { UILabel *_monthLabel; } @property (nonatomic,strong) UICollectionView *ZJCollectionView; @property (nonatomic,strong) NSDate *date; @property (nonatomic,assign) CGRect rect; @property (nonatomic,strong) NSArray *array; @property (nonatomic,strong) NSArray *weekDayArray; @property (nonatomic,strong) UIView *topDateView; @end @implementation ZJCalendar - (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor whiteColor]; [self setTopView]; self.date = [NSDate date]; self.rect = CGRectMake(0, CGRectGetHeight(self.topDateView.frame), frame.size.width, frame.size.height-CGRectGetHeight(self.topDateView.frame)); [self setView:self.rect]; _weekDayArray = @[@"日",@"一",@"二",@"三",@"四",@"五",@"六"]; } return self; } - (void)drawRect:(CGRect)rect { [self addSwipe]; [self getServiceData]; } - (void)setDate:(NSDate *)date { _date = date; NSDateFormatter *f = [[NSDateFormatter alloc] init]; f.dateFormat = @"yyyy-MM-dd"; NSString *strDate = [f stringFromDate:self.date]; _monthLabel.text = strDate; [self.ZJCollectionView reloadData]; } - (void)setTopView{ self.topDateView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.frame), 50)]; self.topDateView.backgroundColor = [UIColor lightGrayColor]; _monthLabel = [[UILabel alloc] initWithFrame:self.topDateView.bounds]; _monthLabel.textAlignment = NSTextAlignmentCenter; _monthLabel.textColor = [UIColor redColor]; _monthLabel.font = [UIFont systemFontOfSize:20]; [self.topDateView addSubview:_monthLabel]; [self addSubview:self.topDateView]; } - (void)setView:(CGRect)frame { CGFloat item_with = CGRectGetWidth(frame)/7; CGFloat item_height = CGRectGetWidth(frame)/7; UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; layout.itemSize = CGSizeMake(item_with, item_height); layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0); layout.minimumInteritemSpacing = 0; layout.minimumLineSpacing = 0; self.ZJCollectionView = [[UICollectionView alloc] initWithFrame:frame collectionViewLayout:layout]; self.ZJCollectionView.backgroundColor = [UIColor whiteColor]; [self.ZJCollectionView registerClass:[ZJCalendarCell class] forCellWithReuseIdentifier:ZJCalendarCellIdentifier]; self.ZJCollectionView.dataSource = self; self.ZJCollectionView.delegate = self; [self addSubview:self.ZJCollectionView]; } - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{ return 2; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ if (section==0) { return _weekDayArray.count; } return 42; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ ZJCalendarCell *cell = (ZJCalendarCell *)[collectionView dequeueReusableCellWithReuseIdentifier:ZJCalendarCellIdentifier forIndexPath:indexPath]; if (indexPath.section==0) { NSString *weekday = [_weekDayArray objectAtIndex:indexPath.row]; if (indexPath.row==0||indexPath.row==6) { cell.dateLabel.textColor = [UIColor colorWithRed:0 green:160.0f/255 blue:223.0f/255 alpha:1.0]; }else{ cell.dateLabel.textColor = [UIColor blackColor]; } cell.dateLabel.text = weekday; [cell hiddenRightLineView]; }else{ NSInteger firstWeekday = [self firstweekdayInThisMonth:self.date]; NSInteger daysInMonth = [self totaldayInThisMonth:self.date]; NSInteger daysInlastMonth = [self totaldayInThisMonth:[self lastMonth:self.date]]; NSInteger day = 0; NSInteger i = indexPath.row; [cell hiddenRightLineView]; if (i < firstWeekday) { cell.dateLabel.textColor = [UIColor lightGrayColor]; cell.dateLabel.text = [NSString stringWithFormat:@"%ld",(long)daysInlastMonth-firstWeekday+i+1]; }else if (i > firstWeekday+daysInMonth-1){ cell.dateLabel.textColor = [UIColor lightGrayColor]; cell.dateLabel.text = [NSString stringWithFormat:@"%ld",(long)i-firstWeekday-daysInMonth+1]; }else{ day = i-firstWeekday+1; cell.dateLabel.textColor = [UIColor blackColor]; NSString *key = [NSString stringWithFormat:@"%d",day]; if (self.array) { for (NSString *testString in self.array) { if ([testString isEqualToString:key]) { cell.dateLabel.textColor = [UIColor orangeColor]; break; } } } cell.dateLabel.text = [NSString stringWithFormat:@"%ld",(long)day]; } } return cell; } - (NSInteger)firstweekdayInThisMonth:(NSDate *)date{ NSCalendar *calendar = [NSCalendar currentCalendar]; calendar.firstWeekday = 1; NSDateComponents *com = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date]; com.day = 1; NSDate *firstDayOfMonthDate = [calendar dateFromComponents:com]; NSInteger firstWeekday = [calendar ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitWeekOfMonth forDate:firstDayOfMonthDate]; return firstWeekday - 1; } - (NSInteger)totaldayInThisMonth:(NSDate *)date{ NSRange daysInMonth = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date]; return daysInMonth.length; } - (NSDate *)lastMonth:(NSDate *)date{ NSDateComponents *com = [[NSDateComponents alloc] init]; com.month = -1; NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:com toDate:date options:0]; return newDate; } - (NSDate *)nextMonth:(NSDate *)date{ NSDateComponents *com = [[NSDateComponents alloc] init]; com.month = 1; NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:com toDate:date options:0]; return newDate; } - (void)left:(UIGestureRecognizer *)left{ [UIView transitionWithView:self duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ self.date = [self nextMonth:self.date]; } completion:^(BOOL finished) { if (finished) { [self getServiceData]; } }]; } - (void)right:(UIGestureRecognizer *)right{ [UIView transitionWithView:self duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ self.date = [self lastMonth:self.date]; } completion:^(BOOL finished) { if (finished) { [self getServiceData]; } }]; } - (void)addSwipe { UISwipeGestureRecognizer *swipLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(left:)]; swipLeft.direction = UISwipeGestureRecognizerDirectionLeft; [self addGestureRecognizer:swipLeft]; UISwipeGestureRecognizer *swipRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(right:)]; swipRight.direction = UISwipeGestureRecognizerDirectionRight; [self addGestureRecognizer:swipRight]; } - (void)getServiceData{ //能夠請求服務器數據,這裏爲了測試,設置了固定的數據; self.array = @[@"13",@"18",@"1",@"14",@"4",@"22"]; [self.ZJCollectionView reloadData]; } @end
(3)關於自定義的cell,主要是一個label和兩個分割線;用的是masonry自適應佈局;code
#import "ZJCalendarCell.h" #import <Masonry.h> #define kScreenWidth CGRectGetWidth([UIScreen mainScreen].bounds) @interface ZJCalendarCell () { UIView *bottomLine; UIView *rightLine; } @end @implementation ZJCalendarCell - (instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor whiteColor]; self.dateLabel = [[UILabel alloc] init]; self.dateLabel.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:self.dateLabel]; __weak typeof(self) weakSelf = self; [self.dateLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(weakSelf.contentView); }]; bottomLine = [[UIView alloc] init]; bottomLine.backgroundColor = [UIColor lightGrayColor]; [self.contentView addSubview:bottomLine]; [bottomLine mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.equalTo(self.contentView.mas_leading); make.trailing.equalTo(self.contentView.mas_trailing); make.height.mas_equalTo(0.5); make.bottom.equalTo(self.contentView.mas_bottom); }]; rightLine = [[UIView alloc] init]; rightLine.backgroundColor = [UIColor lightGrayColor]; [self.contentView addSubview:rightLine]; [rightLine mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.contentView.mas_top); make.trailing.equalTo(self.contentView.mas_trailing); make.width.mas_equalTo(0.5); make.bottom.equalTo(self.contentView.mas_bottom); }]; } return self; } - (void)hiddenRightLineView { if (self.frame.origin.x + self.frame.size.width >= kScreenWidth) { rightLine.hidden = YES; }else{ rightLine.hidden = NO; } } @end
(三)總結;component
這個只是簡易的日曆,功能比較單一;主要是爲了知足當前項目的須要;第三方也有不少相關的控件,並且技術以及功能都比較豐富。orm