简单日历封装

(一)前言

项目中需要签到功能,所以要运用到一个简易日历,原来老版本的日历用户体验相当的不好,所以在这里封装一个简易的日历,关键的点就是:当前月的第一天是星期几以及当前月有多少天,下面看代码。

 

(二)布局;

(1)整个view分两个部分,顶部为一个显示时间的topview,里面在添加一个uilabel显示时间;下部是一个UICollectionView,分为两个section,第一个section是显示星期几;第二个section显示的当前月份的days;

(2)view里面可以加入数据交互,比如从后台获取信息并显示;

#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自适应布局;

#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

(三)总结;

这个只是简易的日历,功能比较单一;主要是为了满足当前项目的需要;第三方也有很多相关的控件,而且技术以及功能都比较丰富。

转载于:https://my.oschina.net/u/1450995/blog/664584

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值