日历开发demo

转载 2016年08月29日 16:38:33

转自:http://blog.csdn.net/jasonblog/article/details/21977481

近期需要写一个交互有点DT的日历控件,具体交互细节这里略过不表。

不过再怎么复杂的控件,也是由基础的零配件组装起来的,这里最基本的就是日历控件。

先上图:


从图中可以看出日历控件就是由一个个小方块组成的,每一行有7个小方块,分别表示一周的星期天到星期六。

给定一个月份,我们首先需要知道这个月有多少周。那么如何确定一个月有多少周呢?

我是这么想的,在NSDate上做扩展:

  1. @interface NSDate (WQCalendarLogic)  

0. 首先需要知道这个月有多少天:

  1. - (NSUInteger)numberOfDaysInCurrentMonth  
  2. {  
  3.     // 频繁调用 [NSCalendar currentCalendar] 可能存在性能问题  
  4.     return [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:self].length;  
  5. }  

1. 确定这个月的第一天是星期几。这样就能知道给定月份的第一周有几天:

  1. - (NSDate *)firstDayOfCurrentMonth  
  2. {  
  3.     NSDate *startDate = nil;  
  4.     BOOL ok = [[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startDate interval:NULL forDate:self];  
  5.     NSAssert1(ok, @"Failed to calculate the first day of the month based on %@", self);  
  6.     return startDate;  
  7. }  
  8.   
  9. - (NSUInteger)weeklyOrdinality  
  10. {  
  11.     return [[NSCalendar currentCalendar] ordinalityOfUnit:NSDayCalendarUnit inUnit:NSWeekCalendarUnit forDate:self];  
  12. }  

2. 减去第一周的天数,剩余天数除以7,得到倍数和余数:

  1. - (NSUInteger)numberOfWeeksInCurrentMonth  
  2. {  
  3.     NSUInteger weekday = [[self firstDayOfCurrentMonth] weeklyOrdinality];  
  4.       
  5.     NSUInteger days = [self numberOfDaysInCurrentMonth];  
  6.     NSUInteger weeks = 0;  
  7.       
  8.     if (weekday > 1) {  
  9.         weeks += 1, days -= (7 - weekday + 1);  
  10.     }  
  11.       
  12.     weeks += days / 7;  
  13.     weeks += (days % 7 > 0) ? 1 : 0;  
  14.       
  15.     return weeks;  
  16. }  

到这里,就可以知道一个月有多少行多少列,从而计算出需要多少个小方块来展示:
  1. @interface WQCalendarTileView : UIView  

这些小方块用一个大方块来承载:
  1. @interface WQCalendarGridView : UIView  
  2.   
  3. @property (nonatomic, weak) id<WQCalendarGridViewDataSource> dataSource;  
  4. @property (nonatomic, weak) id<WQCalendarGridViewDelegate> delegate;  
  5.   
  6. - (void)reloadData;  

和UITableView类似,当WQCalendarGridView调用reloadData接口时,会开始进行布局。而布局所需要的信息由dataSource和delegate提供:
  1. @class WQCalendarGridView;  
  2.   
  3. @protocol WQCalendarGridViewDataSource <NSObject>  
  4.   
  5. @required  
  6.   
  7. - (NSUInteger)numberOfRowsInGridView:(WQCalendarGridView *)gridView;  
  8.   
  9. - (WQCalendarTileView *)gridView:(WQCalendarGridView *)gridView tileViewForRow:(NSUInteger)row column:(NSUInteger)column;  
  10.   
  11. @optional  
  12.   
  13. - (CGFloat)heightForRowInGridView:(WQCalendarGridView *)gridView;  
  14.   
  15. @end  
  16.   
  17. @protocol WQCalendarGridViewDelegate <NSObject>  
  18.   
  19. - (void)gridView:(WQCalendarGridView *)gridView didSelectAtRow:(NSUInteger)row column:(NSUInteger)column;  
  20.   
  21. @end  

每一行的高度,heightForRow,我比较倾向于由dataSource提供 :)

第一个dataSource方法上面已经可以计算出来了,第二个dataSource方法需要对每一个tile进行配置,比如非当前月的以灰色展示,那么我们就需要知道当前月展示中包含的 上个月残留部分,和 下个月的开头部分:

  1. #pragma mark - method to calculate days in previous, current and the following month.  
  2.   
  3. - (void)calculateDaysInPreviousMonthWithDate:(NSDate *)date  
  4. {  
  5.     NSUInteger weeklyOrdinality = [[date firstDayOfCurrentMonth] weeklyOrdinality];  
  6.     NSDate *dayInThePreviousMonth = [date dayInThePreviousMonth];  
  7.       
  8.     NSUInteger daysCount = [dayInThePreviousMonth numberOfDaysInCurrentMonth];  
  9.     NSUInteger partialDaysCount = weeklyOrdinality - 1;  
  10.       
  11.     NSDateComponents *components = [dayInThePreviousMonth YMDComponents];  
  12.       
  13.     self.daysInPreviousMonth = [NSMutableArray arrayWithCapacity:partialDaysCount];  
  14.     for (int i = daysCount - partialDaysCount + 1; i < daysCount + 1; ++i) {  
  15.         WQCalendarDay *calendarDay = [WQCalendarDay calendarDayWithYear:components.year month:components.month day:i];  
  16.         [self.daysInPreviousMonth addObject:calendarDay];  
  17.         [self.calendarDays addObject:calendarDay];  
  18.     }  
  19. }  
  20.   
  21. - (void)calculateDaysInCurrentMonthWithDate:(NSDate *)date  
  22. {  
  23.     NSUInteger daysCount = [date numberOfDaysInCurrentMonth];  
  24.     NSDateComponents *components = [date YMDComponents];  
  25.       
  26.     self.daysInCurrentMonth = [NSMutableArray arrayWithCapacity:daysCount];  
  27.     for (int i = 1; i < daysCount + 1; ++i) {  
  28.         WQCalendarDay *calendarDay = [WQCalendarDay calendarDayWithYear:components.year month:components.month day:i];  
  29.         [self.daysInCurrentMonth addObject:calendarDay];  
  30.         [self.calendarDays addObject:calendarDay];  
  31.     }  
  32. }  
  33.   
  34. - (void)calculateDaysInFollowingMonthWithDate:(NSDate *)date  
  35. {  
  36.     NSUInteger weeklyOrdinality = [[date lastDayOfCurrentMonth] weeklyOrdinality];  
  37.     if (weeklyOrdinality == 7) return ;  
  38.       
  39.     NSUInteger partialDaysCount = 7 - weeklyOrdinality;  
  40.     NSDateComponents *components = [[date dayInTheFollowingMonth] YMDComponents];  
  41.       
  42.     self.daysInFollowingMonth = [NSMutableArray arrayWithCapacity:partialDaysCount];  
  43.     for (int i = 1; i < partialDaysCount + 1; ++i) {  
  44.         WQCalendarDay *calendarDay = [WQCalendarDay calendarDayWithYear:components.year month:components.month day:i];  
  45.         [self.daysInFollowingMonth addObject:calendarDay];  
  46.         [self.calendarDays addObject:calendarDay];  
  47.     }  

相关文章推荐

根据OLAMI平台开发的日历Demo

前言 编写语法 前言 在自然语言处理中,语义理解一直是个难题。 最近发现OLAMI语义平台提供了自然语言语义理解 API ,而且支持自定义语法,所以决定写一个日历的Demo来看一下效果。...

iOS 简单日历(配Demo下载)

一、样式       采用一个UICollectionView , 其中“星期”使用 UICollectionView 的header显示;日期采用自定义的 UICollectionViewCell ...

日历组件demo

日历组件插件,可随意选择日期datetime.js: // onfocus="currentWeek(this);" (function($){ $(".datetimeInputCls")...

基于vue的日历小demo

这个批次拿到了一个我一开始认为比较棘手的问题,是一个带特殊功能的日历。呐~设计图 因为现在用vue比jq熟练了,之前没接触过vue的日历,基于jq的日历五花八门的,所以还是决定基于v...

jQuery插件实战之fullcalendar(日历插件)Demo

jQuery的插件非常多,应用的场景也非常丰富,今天我这里给大家介绍一款非常实用的日历页面开发插件 - fullcalendar,目前最新版本是1.5.1,使用这款插件能够快速帮助你快速编程实现基于w...

日历签到demo 实现记录

Android日历签到

可动态切换日历demo

demo地址:http://codepen.io/tianzi77/pen/vOQbPY看别人的demo.自己也尝试写了一下;小日历。结构: 1JAN...

canvas日历绘制 简单demo

canvas绘制本月日历,效果如下 html,body{ margin :0 0; padding: 0 0; width: 10...

jQuery插件实战之fullcalendar(日历插件)Demo

jQuery的插件非常多,应用的场景也非常丰富,今天我这里给大家介绍一款非常实用的日历页面开发插件 - fullcalendar,目前最新版本是1.5.1,使用这款插件能够快速帮助你快速编程实现基于w...

日历控件demo

  • 2015-05-15 20:01
  • 1.02MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)