1、程序结构:
千言万语,不如一张图来的清晰
1) 由于CalendarController包含了一个UITableView指针,因此CalendarController需要实现UITableDataSource以及UITableViewDelegate与UITableView进行交互。 2) UITableView包含多个CalendarView,这样就能利用UITableView的手势滑动功能以及Cell重用功能。 3) CalendarView继承自UIControl,因为UIControl将相对底层的触摸事件转换为容易操作的控件事件。主要为了使用UIControlEventTouchUpInside这个事件。 4) CalendarDelegate仿照ios mvc模式,用于类之间的解耦(面向接口编程)以及类之间的通信。
2、 CalendarDelegate 协议:
@protocol CalendarDelegate//年月和UITableView以及其中CalendarView之间关系映射 //具体见下面代码分析 -(int) calcCalendarCount; -(SDate) mapIndexToYearMonth : (int) index; -(int) mapYearMonthToIndex : (SDate) date; //用于显示到指定的年月范围 -(void) showCalendarAtYearMonth : (SDate) date; //用于时间期限管理以及选中判断 -(BOOL) isInSelectedDateRange : (SDate) date; -(void) setSelectedDateRangeStart : (SDate) start end : (SDate) end; -(void) setEndSelectedDate : (SDate) end; //迫使整个UITableView重绘 -(void) repaintCalendarViews; //计数器,用于判断touch次数 -(void) updateHitCounter; -(int) getHitCounter; @end
3、 CalendarController:
CalendarController的声明//.h文件接口声明 #import@interface ViewController :UIViewController @end
//.m文件 #import "ViewController.h" #import "CalendarDelegate.h" #import "CalendarView.h" //实现了如下三个delegate @interface ViewController ()CalendarDelegate的协议函数calcCalendarCount的实现和调用{ //用于计算出多少个月历,具体见下面代码 int _startYear; int _endYear; //每个月历控件的高度,上面的个数和此地的高度,就可以计算整个UITableView的高度以及进行定位操作 float _calendarHeight; //用于选中操作时候,时间范围的比较(time_t实际是个64位的整型值,适合做比较操作,具体看实现代码) time_t _startTime; time_t _endTime; } //选中值的年月表示方式,方便显示而已,实际操作都转换成time_t类型 @property (nonatomic,assign) SDate begDate; @property (nonatomic,assign) SDate endDate; //点击计数器,用于确定当前点击的奇偶性,因此改月历控件涉及两次操作,用于区域选者 @property (nonatomic) int hitCounter; //作为Calendar的父容器,用于处理滑动以及cell重用 @property (weak, nonatomic) IBOutlet UITableView *tableView; @end
-(int) calcCalendarCount
{
SDate date;
date_get_now(&date);
//计算出当前的年月到n年前的1月份的月数
//加设当前为2016年8月,n为5,则月份范围为[2011年1月---2016年8月 总计月数为68],具体算法如下:
int diff = _endYear - _startYear + 1;
diff = diff * 12;
diff -= 12 - date.month;
return diff;
}
//UITableView的DatatSource有个必须实现的协议函数,用于返回当前UITableView可以容纳的总数:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int ret = [self calcCalendarCount];
return ret;
}
UITableViewDelegate需要实现的一个协议函数:
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//返回的是当前的calendarView的高度
//UITableView需要知道月历(月份)的个数以及月历控件的高度,就可以计算出整个UITableView的Content的height了
return _calendarHeight;
}


