继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(二A)

jackyBu
关注TA
已关注
手记 22
粉丝 34
获赞 314

二、IOS实现版本:

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 <NSObject>

//年月和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 <UIKit/UIKit.h>

@interface ViewController :UIViewController
@end
//.m文件
#import "ViewController.h"
#import "CalendarDelegate.h"
#import "CalendarView.h"

//实现了如下三个delegate
@interface ViewController () <UITableViewDataSource,UITableViewDelegate,CalendarDelegate>
{
    //用于计算出多少个月历,具体见下面代码
    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
CalendarDelegate的协议函数calcCalendarCount的实现和调用
-(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;
}
打开App,阅读手记
3人推荐
发表评论
随时随地看视频慕课网APP

热门评论

再次修正一个bug,已上传github
-(void) setYearMonth:(int)year month:(int)month
{
calendar_set_year_month(&_calendar, year, month);
if (_calendar.date.month > 1) {
_lastMonthDayCount = date_get_month_of_day(_calendar.date.year,_calendar.date.month-1);
}else{
_lastMonthDayCount = date_get_month_of_day(_calendar.date.year-1,12);
}
[self setNeedsDisplay];
}

修正一个bug,已上传github

void date_map_index_to_year_month(SDate* to,int startYear,int idx)

{

assert(to);

to->year = startYear + idx / 12;

to->month = idx % 12 + 1;

//to->day = -1;

//修改成如下代码。应该为1而不是-1

to->day = 1;

}


查看全部评论