最近在做一个旅游相关的项目,用户在选择出游日期的时候,每天的价格不一样,所有需要开发一个价格日历的组件。就是在原有的日历控件的基础上,再增加一排价格的显示。如图所示:
C8951431-1525-4616-9E37-F86DBDF48BF3.jpeg实现思路
每个月的天数都不一样,二月份有的时候是28天,有的时候是29天,小月是30天,大月是31天。日历控件上每次会显示42(6*7)个日期,为什么是42个日期呢?一周有七天,显示六周。42天由上一个月的最后几天,加上本月的全部天数,和下一个月的头几天组成。最后在显示日期的时候,把上个月的末几天和下个月的头几天全部隐藏,剩下看到的就是本月的天数了。
1、创建42个label,用于显示日期
界面上创建了42个lab1,用来显示日期;创建了42个lab2,用来显示价格;42个button,用来点击日期。把这些控件全部用对应的数组存放起来,需要用的时候,再从数组里面取出来。
- (void)initCalendarWeekUI
{
for (NSInteger i=0; i<kButtonNum; i++) {
NSInteger x = i % 7;
NSInteger y = i / 7;
UIButton *btnDay = [[UIButton alloc] initWithFrame:CGRectMake(5+x*(labWidth+10), 50+y*(labWidth+10)+3, labWidth, labWidth)];
[btnDay setTag:i];
[btnDay.titleLabel setFont:kFont_Large];
[btnDay addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
[btnDay setBackgroundColor:[UIColor whiteColor]];
btnDay.layer.cornerRadius = 3;
btnDay.layer.masksToBounds = YES;
[_bgView addSubview:btnDay];
UILabel *lab1 = [[UILabel alloc] initWithFrame:CGRectMake(5+x*(labWidth+10), 55+y*(labWidth+10)+3, labWidth, (labWidth-10)/2)];
lab1.textColor = kColor_Black;
lab1.font = kFont_Middle;
lab1.textAlignment = NSTextAlignmentCenter;
[_bgView addSubview:lab1];
UILabel *lab2 = [[UILabel alloc] initWithFrame:CGRectMake(5+x*(labWidth+10), 55+(labWidth-10)/2+y*(labWidth+10)+3, labWidth, (labWidth-10)/2)];
lab2.textColor = kColor_Black;
lab2.font = kFont_Middle;
lab2.textAlignment = NSTextAlignmentCenter;
[_bgView addSubview:lab2];
[arrButton addObject:btnDay];
[arrLab1 addObject:lab1];
[arrLab2 addObject:lab2];
}
}
如图所示:
D60B0847-917F-4F26-8286-A741A178694D.jpeg2、创建CalendarModel,用于存放日期相关的数据
@interface CalendarModel : NSObject
@property (nonatomic, assign) NSInteger yearInt;
@property (nonatomic, assign) NSInteger monthInt;
@property (nonatomic, assign) NSInteger dateInt;
@property (nonatomic, assign) NSInteger addPrice;
//自己添加的属性
@property (nonatomic, assign) BOOL isSelected;
@property (nonatomic, assign) BOOL isToday;
@property (nonatomic, assign) BOOL isShow;
@property (nonatomic, assign) BOOL isDefaultMoney;
@property (nonatomic, assign) BOOL isPastDate; //过去的时间
@property (nonatomic, assign) NSInteger index;
@property (nonatomic, strong) NSDate *date;
@end
3、刷新某个月的数据
//刷新一个月的数据
- (void)reloadData
{
NSDate *currentDate = [NSDate getDateWithYear:currentYear month:currentMonth day:1];
NSInteger firstDay = [NSDate getWeekdayOfDate:currentDate];
NSInteger totalDays = [currentDate daysOfMonth];
NSInteger year = currentYear;
NSInteger month = currentMonth;
NSInteger day = 0;
//获取上个月的数据
NSDate *preDate;
if (currentMonth == 1) {
preDate = [NSDate getDateWithYear:currentYear-1 month:12 day:1];
} else {
preDate = [NSDate getDateWithYear:currentYear month:currentMonth-1 day:1];
}
NSInteger preDays = [currentDate daysOfMonth];
_labTitle.text = [currentDate stringWithFormat:@"yyyy-MM"];
self.listData = [[NSMutableArray alloc] init];
for (NSInteger i=0; i<kButtonNum; i++) {
CalendarModel *model = [[CalendarModel alloc] init];
model.index = I;
if (i < firstDay) { //前一个月日期
year = currentYear;
month = currentMonth - 1;
if (month < 1) {
month = 12;
year = currentYear - 1;
}
day = preDays+i-firstDay+1;
model = [self calendarModel:model year:year month:month day:day price:100 isShow:NO];
} else if (i < totalDays + firstDay) { //当前月日期
year = currentYear;
month = currentMonth;
day = i-firstDay+1;
model = [self calendarModel:model year:year month:month day:day price:100 isShow:YES];
} else { // 下一个月日期
year = currentYear;
month = currentMonth + 1;
if (month > 12) {
month = 1;
year = currentYear + 1;
}
model = [self calendarModel:model year:year month:month day:day price:100 isShow:NO];
}
for (NSInteger j=0; j<selectedItem.count; j++) {
CalendarModel *selectModel = selectedItem[j];
if (model.yearInt == selectModel.yearInt && model.monthInt == selectModel.monthInt && model.dateInt == selectModel.dateInt)
{
model.isSelected = YES;
break;
}
}
[self showOneDayOfCalendar:model];
[self.listData addObject:model];
}
}
4、获取上一个月或者下一个月的数据
//前一月
- (void)btnPreviousMonth:(UIButton *)btn
{
currentMonth --;
if (currentMonth < 1) {
currentYear --;
currentMonth = 12;
}
[self reloadData];
}
//后一月
- (void)btnNextMonth:(UIButton *)btn
{
currentMonth ++;
if (currentMonth > 12) {
currentYear ++;
currentMonth = 1;
}
[self reloadData];
}
5、控制某一天日期数据的显示
每一个日期对应一个CalendarModel,该日期是否显示,显示的内容全部由model里面的数据控制。
//显示某一天的日期
- (void)showOneDayOfCalendar:(CalendarModel *)model
{
UIButton *btn = [arrButton objectAtIndex:model.index];
UILabel *lab1 = [arrLab1 objectAtIndex:model.index];
UILabel *lab2 = [arrLab2 objectAtIndex:model.index];
if (model.isShow) {
if (!model.isPastDate) {
if (model.isSelected) {
btn.enabled = YES;
lab1.textColor = model.isToday ? kColor_Red : kColor_White;
lab2.textColor = kColor_White;
lab1.text =STR_NUM(model.dateInt);
lab2.text = STR_MONEY(STR_NUM(model.addPrice));
btn.backgroundColor = kColor_Orange;
} else {
btn.enabled = YES;
lab1.textColor = model.isToday ? kColor_Red : kColor_Black;
lab2.textColor = kColor_Orange;
lab1.text =STR_NUM(model.dateInt);
lab2.text = STR_MONEY(STR_NUM(model.addPrice));
btn.backgroundColor = kColor_White;
}
} else {
btn.enabled = NO;
lab1.text = STR_NUM(model.dateInt);
lab2.text = STR_MONEY(STR_NUM(0));
lab1.textColor = lab2.textColor = kColor_LightGray;
btn.backgroundColor = kColor_White;
}
} else {
btn.enabled = NO;
lab1.textColor = lab2.textColor = btn.backgroundColor = kColor_White;
}
}
6、点击某一天进行选中
//点击某一天
- (void)btnClick:(UIButton *)btn
{
CalendarModel *model = _listData[btn.tag];
if (model.isSelected) {
model.isSelected = NO;
[selectedItem removeObject:model];
} else {
model.isSelected = YES;
[selectedItem addObject:model];
}
[self showOneDayOfCalendar:model];
}
与日期相关的一些处理方法,都放在了NSDate+Helper
类里面
@interface NSDate (Helper)
- (NSString *)stringWithFormat:(NSString *)format;
- (NSInteger)yearIndex;
- (NSInteger)monthIndex;
+ (BOOL)isSameDay:(NSDate*)date1 date2:(NSDate*)date2;
//获取一个月有多少天
- (NSInteger)daysOfMonth;
//计算某个日期对应的星期
+ (NSInteger)getWeekdayOfDate:(NSDate *)date;
//将世界时间转化为中国区时间
- (NSDate *)worldTimeToChinaTime:(NSDate *)date;
//传入年月日,返回对应的NSDate
+ (NSDate *)getDateWithYear:(NSInteger)year month:(NSUInteger)month day:(NSInteger)day;
@end
最终的演示效果,如下图所示:
test.gif
网友评论