美文网首页
iOS价格日历

iOS价格日历

作者: 袁灿 | 来源:发表于2019-02-13 13:55 被阅读0次

最近在做一个旅游相关的项目,用户在选择出游日期的时候,每天的价格不一样,所有需要开发一个价格日历的组件。就是在原有的日历控件的基础上,再增加一排价格的显示。如图所示:

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.jpeg

2、创建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

GitHub下载地址

相关文章

网友评论

      本文标题:iOS价格日历

      本文链接:https://www.haomeiwen.com/subject/njtdeqtx.html