博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS开发一款小巧简洁的日历控件
阅读量:5737 次
发布时间:2019-06-18

本文共 8040 字,大约阅读时间需要 26 分钟。

hot3.png

iOS开发一款小巧简洁的日历控件

一、引言

        日 历是iOS开发中有时会用到的一个UI控件,网上开源的代码也很多,我浏览过一些,大致有两种模式,一种是日历的逻辑由开发者自己实现,通过计算闰年与平 年来确定月份天数,另外一种模式是通过NSDate这个时间类,来获取日历的信息。我个人认为后一种更加安全,代码性能也会更加优质,下面就是我用这种模 式实现的一个日历控件。

二、设计思路

1、先来看下效果吧

151734_UMxO_2340880.png        151735_BsEo_2340880.png           151735_ZUgv_2340880.png

2、我们需要实现的功能

(1)每行7天,对应星期,列数为将当前月显示完全

(2)今日标红

(3)点击的日期背景填充

(4)提供特殊标记,用于标记计划日,节日等

(5)左右无限翻页,直到世界起源和末日

 3、设计步骤

(1)设计一个日历模型

#import "YHBaseModel.h"@interface YHBaseDateModel : YHBaseModel@property(nonatomic,strong)NSString * year;@property(nonatomic,strong)NSString * month;@property(nonatomic,strong)NSString * day;@end

(2)向系统的NSDate类中添加一些扩展方法,便于我们使用

//头文件部分@interface NSDate (YHBaseCalendar)/** *获取当前月的天数 */- (NSUInteger)YHBaseNumberOfDaysInCurrentMonth;/** *获取本月第一天 */- (NSDate *)YHBaseFirstDayOfCurrentMonth;//下面这些方法用于获取各种整形的数据/** *确定某天是周几 */-(int)YHBaseWeekly;/** *年月日 时分秒 */-(int)getYear;-(int)getMonth;-(int)getDay;-(int)getHour;-(int)getMinute;-(int)getSecond;@end//实现部分@implementation NSDate (YHBaseCalendar)-(NSUInteger)YHBaseNumberOfDaysInCurrentMonth{     return [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:self].length;  }- (NSDate *)YHBaseFirstDayOfCurrentMonth{    NSDate *startDate = nil;    BOOL ok = [[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startDate interval:NULL forDate:self];    NSAssert1(ok, @"Failed to calculate the first day of the month based on %@", self);    return startDate;}-(int)YHBaseWeekly{     return (int)[[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit inUnit:NSWeekCalendarUnit forDate:self];}-(int)getYear{    NSCalendar *calendar = [NSCalendar currentCalendar];    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];    return (int)dateComponent.year;}-(int)getMonth{    NSCalendar *calendar = [NSCalendar currentCalendar];    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];    return (int)dateComponent.month;}-(int)getDay{    NSCalendar *calendar = [NSCalendar currentCalendar];    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];    return (int)dateComponent.day;}-(int)getHour{    NSCalendar *calendar = [NSCalendar currentCalendar];    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];    return (int)dateComponent.hour;}-(int)getMinute{    NSCalendar *calendar = [NSCalendar currentCalendar];    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];    return (int)dateComponent.minute;}-(int)getSecond{    NSCalendar *calendar = [NSCalendar currentCalendar];    NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:self];    return (int)dateComponent.second;}@end

(3)设计我们的UI控件

//头文件部分@interface YHBaseCalendarView : YHBaseView@property(nonatomic,strong)NSDate * currentDate;//标记数组 用于标记特殊日期 这个数组中存放的必须是YHBaseDateModel 对象@property(nonatomic,strong)NSArray * markArray;@property(nonatomic,weak)id
 delegate;@end//实现部分@interface YHBaseCalendarView()
{    //星期    UIView * _headView;    //日历的展示    UIView * _bodyViewL;    UIView * _bodyViewM;    UIView * _bodyViewR;    //滑动功能的支持    UIScrollView * _scrollView;    NSDate * _today;        YHBaseDateModel * _selectModel;}@end@implementation YHBaseCalendarView-(void)reloadView{    _currentDate = [NSDate date];    _today = [NSDate date];    _selectModel = [[YHBaseDateModel alloc]init];    _selectModel.year = [NSString stringWithFormat:@"%d",[_today getYear]];    _selectModel.month =[NSString stringWithFormat:@"%d",[_today getMonth]];    _selectModel.day = [NSString stringWithFormat:@"%d",[_today getDay]];    _scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 30, self.frame.size.width, self.frame.size.height)];    _scrollView.contentSize = CGSizeMake(3*self.frame.size.width, 0);    _scrollView.contentOffset = CGPointMake(self.frame.size.width, 0);    _scrollView.pagingEnabled=YES;    _scrollView.delegate=self;    [self addSubview:_scrollView];    _bodyViewL = [[UIView alloc]initWithFrame:CGRectMake(0, 0, _scrollView.frame.size.width, _scrollView.frame.size.height)];    [_scrollView addSubview:_bodyViewL];    _bodyViewM = [[UIView alloc]initWithFrame:CGRectMake(_scrollView.frame.size.width,0,  _scrollView.frame.size.width, _scrollView.frame.size.height)];    [_scrollView addSubview:_bodyViewM];    _bodyViewR = [[UIView alloc]initWithFrame:CGRectMake(_scrollView.frame.size.width*2, 0, _scrollView.frame.size.width, _scrollView.frame.size.height)];    [_scrollView addSubview:_bodyViewR];    //展示星期    _headView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, 30)];    _headView.backgroundColor = [UIColor redColor];    NSArray * weekArray = @[@"SUN",@"MON",@"TUES",@"WED",@"THUR",@"FRI",@"SAT"];    for (int i=0; i<7; i++) {        UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(self.frame.size.width/7*i, 0, self.frame.size.width/7, 30)];        if (i!=0&&i!=6) {            label.backgroundColor = [UIColor redColor];        }else{            label.backgroundColor = [UIColor purpleColor];        }        label.text=weekArray[i];        label.textAlignment = NSTextAlignmentCenter;        label.layer.borderWidth=1;        label.layer.borderColor = [[UIColor grayColor]CGColor];        label.font = [UIFont boldSystemFontOfSize:16];        label.layer.borderColor=[[UIColor grayColor] CGColor];        label.textColor = [UIColor whiteColor];        label.layer.borderWidth = 1;        [_headView addSubview:label];    }    [self addSubview:_headView];        [self creatViewWithData:_currentDate onView:_bodyViewM];    [self creatViewWithData:[YHBaseDateTools getPreviousframDate:_currentDate] onView:_bodyViewL];    [self creatViewWithData:[YHBaseDateTools getNextMonthframDate:_currentDate] onView:_bodyViewR];}//核心的构造方法-(void)creatViewWithData:(id)data onView:(UIView *)bodyView{    NSDate * currentDate = (NSDate *)data;    //获取当前月有多少天    int monthNum = (int)[currentDate YHBaseNumberOfDaysInCurrentMonth];    //获取第一天的日期    NSDate * firstDate = [currentDate YHBaseFirstDayOfCurrentMonth];    //确定这一天是周几    int weekday = [firstDate YHBaseWeekly];    //确定创建多少行    int weekRow=0;    int tmp=monthNum;    if (weekday!=7) {        weekRow++;        tmp=monthNum-(7-weekday);    }    weekRow += tmp/7;    weekRow += (tmp%7)?1:0;    //开始创建按钮    /**     *这里的逻辑是有问题的,应该设计成cell的复用机制,而不应该重复耗性能的创建 有时间在优化     */#warning 可以优化哦     NSArray * array = [bodyView subviews];    for (UIView * v in array) {        [v removeFromSuperview];    }    int nextDate = 1;    //行    for (int i=0; i

(4)为用户交互设计的协议

@protocol YHBaseCalendarViewDelegate
-(void)YHBaseCalendarViewSelectAtDateModel:(YHBaseDateModel *)dateModel;-(void)YHBaseCalendarViewScrollEndToDate:(YHBaseDateModel *)dateModel;@end

三、插个小广告

        控件的源码在中,这是我封装的一套基于Cocoa与Foundation的更易用的开发框架,其中也对AFN,CRLabel,SDImage,MJRefresh进行了集成,有易用的下载框架,缓存框架,错误处理框架,皮肤管理框架等,也有支持加载HTML并且异步缓存图片的view,边下边播并做缓存的AVAudioPlayer,以及各种自定义性能很强的view控件,如用block创建的按钮,提示框以及对json和模型做相关映射的处理类,如果这些东西有帮到你,我很开心,如果你发现一些问题或者优化建议,请一定告知我,我将十分感激,QQ316045346

 

专注技术,热爱生活,交流技术,也做朋友。

——珲少 QQ群:203317592

转载于:https://my.oschina.net/u/2340880/blog/502361

你可能感兴趣的文章
CSS中规则@media的用法
查看>>
pychecker:分析你的python代码
查看>>
css 默认不显示 之后显示
查看>>
我的友情链接
查看>>
DNS显性+隐性URL转发原理
查看>>
我的友情链接
查看>>
网易有道 IP地址、手机号码归属地和身份证 查询接口API
查看>>
鼠标停留在GridView某一行时行的颜色改变
查看>>
系列3:WAS Liberty Profile hello mysql jdbc
查看>>
基础知识:python模块的导入
查看>>
Android MVC之我的实现
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
关于批处理-1
查看>>
Tomcat部署Web应用方法总结
查看>>
Python3 django2.0 字段加密 解密 AES
查看>>
CCNA实验之:网络地址转换(NAT)实验
查看>>
计算机网络原理笔记-停止等待协议
查看>>
确定当前记录和下一条记录之间相差的天数
查看>>
sql语句返回主键SCOPE_IDENTITY()
查看>>