工作记录,加深记忆,方便以后查询。
自定义日历从结构上来分,可以分为月和日。月可以用UITableView来实现,一个section,每个section只有一个cell作为一个月来显示。日是每个月的基本元素,可以用UICollectionView来实现。
首先分析月:这个很容易确定,只要基于当天来计算出当前月。然后以当前月为基础开始自增,可以计算出任意月在UITableView上的位置,属于第几个section。
分析日:上面已经说了,每个cell是一个月,那么也就是每一个cell就是一个UICollectionView,那么每一天就是UICollectionViewCell。这样就要知道每个月有多少天,每个月的第一天是星期几,每个月有几周。确定了这些基础数据,既能够确定出每个月的具体高度。
下面是提取这些数据的具体方法:
1、定义 MonthModel 和 DayModel
@interface MonthModel : NSObject
////年
@property (nonatomic, assign) NSUInteger year;
////月
@property (nonatomic, assign) NSUInteger month;
////一个月有多少天
@property (nonatomic, assign)NSUInteger days;
////每个月第一天是星期几
@property (nonatomic, assign) NSUInteger firstWeekDay;
////一周7天可以排几行
@property (nonatomic, assign) NSUInteger lineCount;
/////用一个月的任意一天初始化
- (instancetype)initWithDate:(NSDate*)inDate;
@end
@interface DayModel : NSObject
////年
@property (nonatomic, assign) NSInteger year;
////月
@property (nonatomic, assign) NSInteger month;
////日
@property (nonatomic, assign) NSInteger day;
////星期几
@property (nonatomic, strong) NSString* weakDay;
@end
2、 一个个获取初始化数据
+ (NSDateFormatter*)dataFormatter {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
[dateFormatter setLocale:[NSLocale currentLocale]];
return dateFormatter;
}
////-- 获取年
+ (NSInteger)year:(NSString*)date {
NSDateFormatter *dateFormatter = [[self class] dataFormatter];
NSDate *startDate = [dateFormatter dateFromString:date];
NSDateComponents*components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:startDate];
return components.year;
}
//// -- 获取月
+ (NSInteger)month:(NSString*)date {
NSDateFormatter *dateFormatter = [[selfclass] dataFormatter];
NSDate *startDate = [dateFormatter dateFromString:date];
NSDateComponents*components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:startDate];
return components.month;
}
////-- 获取日
+ (NSInteger)day:(NSString*)date {
NSDateFormatter *dateFormatter = [[NSDate class] dataFormatter];
NSDate *startDate = [dateFormatter dateFromString:date];
NSDateComponents*components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:startDate];
return components.day;
}
/////-- 获得当前月份第一天星期几
+ (NSInteger)firstWeekdayInThisMonth:(NSDate*)date {
NSCalendar *calendar = [NSCalendar currentCalendar];
//设置每周的第一天从周几开始,默认为1,从周日开始
[calendar setFirstWeekday:1];//1.Sun. 2.Mon. 3.Thes. 4.Wed. 5.Thur. 6.Fri. 7.Sat.
NSDateComponents *comp = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:date];
[compsetDay:1];
NSDate *firstDayOfMonthDate = [calendar dateFromComponents:comp];
NSUInteger firstWeekday = [calendar ordinalityOfUnit:NSCalendarUnitWeekday inUnit:NSCalendarUnitWeekOfMonth forDate:firstDayOfMonthDate];
//若设置从周日开始算起则需要减一,若从周一开始算起则不需要减
return firstWeekday -1;
}
/// 获取当前月有多少天
+ (NSInteger)totaldaysInMonth:(NSDate*)date {
NSRange daysInLastMonth = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
return daysInLastMonth.length;
}
3、基础数据获取完,就是怎么在UI上展示
首先是最外层的月(比较简单的,这里获取这些数据主要是来确定,月cell的高度 和 从星期几开始显示):
- (void)setDate:(NSDate*)inDate
{
NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:inDate];
_year= components.year;
_month= components.month;
_days = [NSDate totaldaysInMonth:inDate];
_firstWeekDay = [NSDate firstWeekdayInThisMonth:inDate];
_lineCount= [NSDatelineNum:inDate];
}
@end
再就是每个月的具体日的显示(这里用了一个小技巧,因为每个月的第一天不一定是周一, 所以用cell下表和第一天是周几做比较。>=0,则表示这个cell应该显示 ):
- (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath
{
DayCollectionCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCollectionViewCellIdentifier forIndexPath:indexPath];
NSIntegerday = indexPath.row-mMonth.firstWeekDay+1;
[cellsetDay:(day<=mMonth.days? day:-1) withMonth:mMonth];
returncell;
}
//////日期的显示
- (void)setDay:(NSInteger)inDay withMonth:(MonthModel*)inMonth
{
[mDay setYear:inMonth.year];
[mDay setMonth:inMonth.month];
if(inDay >0)
{///显示日期}
else
{
[mDayLabel setText:@""];
[mDesLabel setText:@""];
[mDay setDay:-1];
[mDayLabel setBackgroundColor:kAppBackgroundColor];
}
}
/////
这篇文章只是把主要的思路和要用的方法写了一下,做个记录。
最主要的就是怎么计算month cell的高度,和每个月从周记开始显示day。
网友评论