iOS開發(fā)類攜程日歷,價(jià)格日歷,單選,多選,可選不可選

之前開發(fā)也遇到過酒店,火車票日歷,我用了一款第三方軟件,前期還行,隨著后期功能(業(yè)務(wù))增多,就不好使了,特別是那個(gè)循環(huán)架構(gòu),年 月 日這種的,修改起來特別麻煩。
新增業(yè)務(wù)例如:
1、價(jià)格日歷,景點(diǎn)價(jià)格日歷,機(jī)票價(jià)格日歷
2、基地日歷,我們基地價(jià)格分批次的 1-8天 110元/天,9-20天100 ,21-30天90,這就要求選擇開始日期后,重新刷新數(shù)據(jù),只能選擇天數(shù)區(qū)域內(nèi)的時(shí)間。
3、活動(dòng)日歷,活動(dòng)不是每天搞,隔三差五的,一句話就是可點(diǎn)不可點(diǎn),傳日期輸入,處理后展示出來。

先上圖。
日歷.gif
#define MSS_SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
#define MSS_SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
#define MSS_UTILS_COLORRGB(r,g,b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
#define MSS_Iphone6Scale(x) ((x) * MSS_SCREEN_WIDTH / 375.0f)
#define MSS_ONE_PIXEL (1.0f / [[UIScreen mainScreen] scale])

/*定義屬性*/

// 選擇點(diǎn)擊顏色
#define SelectedColor [UIColor cyanColor]
// 被選中間顏色
#define SelMiddleColor [UIColor greenColor]


// DateLabel默認(rèn)文字顏色
#define MSS_TextColor [UIColor blackColor]
// DateLabel選中時(shí)的背景色
#define MSS_SelectBackgroundColor MSS_UTILS_COLORRGB(29, 154, 72)
// DateLabel選中后文字顏色
#define MSS_SelectTextColor [UIColor whiteColor]
// SubLabel文字顏色
#define MSS_SelectSubLabelTextColor MSS_UTILS_COLORRGB(29, 154, 180);
// SubLabel選中開始文字
#define MSS_SelectBeginText @"開始"
// SubLabel選中結(jié)束文字
#define MSS_SelectEndText @"結(jié)束"
// 節(jié)日顏色
#define MSS_HolidayTextColor [UIColor purpleColor]
// 周末顏色
#define MSS_WeekEndTextColor [UIColor redColor]
// 不可點(diǎn)擊文字顏色
#define MSS_TouchUnableTextColor MSS_UTILS_COLORRGB(150, 150, 150)
// 周視圖高度
#define MSS_WeekViewHeight 60
// headerView線顏色
#define MSS_HeaderViewLineColor [UIColor lightGrayColor]
// headerView文字顏色
#define MSS_HeaderViewTextColor [UIColor blackColor]
// headerView高度
#define MSS_HeaderViewHeight 50
// 彈出層文字顏色
#define MSS_CalendarPopViewTextColor [UIColor whiteColor]
// 彈出層背景顏色
#define MSS_CalendarPopViewBackgroundColor [UIColor blackColor]

typedef NS_ENUM(NSInteger, MSSCalendarViewControllerType)
{
    MSSCalendarViewControllerLastType = 0,// 只顯示當(dāng)前月之前
    MSSCalendarViewControllerMiddleType,// 前后各顯示一半
    MSSCalendarViewControllerNextType// 只顯示當(dāng)前月之后
};

typedef NS_ENUM(NSInteger, MSSCalendarWithUserType)
{
    MSSCalendarHotelType = 0,  // 酒店   入住 --- 離店
    MSSCalendarTrainType,      // 火車票,飛機(jī)票,單選無價(jià)格
    MSSCalendarAplaceType,     // 基地   價(jià)格
    MSSCalendarSecnicType,     // 景點(diǎn)   價(jià)格
    MSSCalendarPlaneType,      // 機(jī)票
    MSSCalendarActivityType    // 活動(dòng),線路

};

可以自定義以上屬性,什么顏色,類型什么的。

核心思路就在這塊,簡(jiǎn)單明了,傳的有一個(gè)參數(shù)limitMonth,顯示幾個(gè)月的數(shù)據(jù),MSSCalendarViewControllerNextType就是今天以后, components.month -= 1;獲取當(dāng)前月份減一,不要問為什么減一,打隔斷點(diǎn)看看就知道了,MSSCalendarViewControllerLastType這是今天以前的limitMonth月的日期。


- (NSArray *)getCalendarDataSoruceWithLimitMonth:(NSInteger)limitMonth type:(MSSCalendarViewControllerType)type
{
    NSMutableArray *resultArray = [[NSMutableArray alloc]init];
    
    NSDateComponents *components = [self dateToComponents:_todayDate];
    components.day = 1;
    if(type == MSSCalendarViewControllerNextType)
    {
        components.month -= 1;
    }
    else if(type == MSSCalendarViewControllerLastType)
    {
        components.month -= limitMonth;
    }
    else
    {
        components.month -= (limitMonth + 1) / 2;
    }
    NSInteger i = 0;
    for(i = 0;i < limitMonth;i++)
    {
        components.month++;
        MSSCalendarHeaderModel *headerItem = [[MSSCalendarHeaderModel alloc]init];
        NSDate *date = [self componentsToDate:components];
        [_dateFormatter setDateFormat: @"yyyy年MM月"];
        NSString *dateString = [_dateFormatter stringFromDate:date];
        headerItem.headerText = dateString;
        headerItem.calendarItemArray = [self getCalendarItemArrayWithDate:date section:i];   // section就是當(dāng)月數(shù)據(jù)頁面的位置
        [resultArray addObject:headerItem];
    }
    return resultArray;
}

一共limitMonth個(gè)月,從第一個(gè)月開始排序,整理數(shù)組。下面是每一個(gè)單獨(dú)月的日期數(shù)據(jù)


// 得到每一天的數(shù)據(jù)源
- (NSArray *)getCalendarItemArrayWithDate:(NSDate *)date section:(NSInteger)section
{
    NSMutableArray *resultArray = [[NSMutableArray alloc]init];
    NSInteger tatalDay = [self numberOfDaysInCurrentMonth:date];  // 本月多少天
    NSInteger firstDay = [self startDayOfWeek:date];  // 本月第一天是周幾
     // 0 星期日  1  星期一      6星期六
    
    NSDateComponents *components = [self dateToComponents:date];
    
    // 判斷日歷有多少列
    // 一共多少天 加 第一天是周幾就可以算出本月cell的數(shù)量

    NSInteger tempDay = tatalDay + (firstDay - 1);
    NSInteger column = 0;
    if(tempDay % 7 == 0)
    {
        column = tempDay / 7;
    }else{
        column = tempDay / 7 + 1;
    }
    
    NSInteger i = 0;
    NSInteger j = 0;
    components.day = 0;
    for(i = 0;i < column;i++)
    {
        for(j = 0;j < 7;j++)
        {
            if(i == 0 && j < firstDay - 1)  // 本月第一天前的數(shù)據(jù)
            {
                MSSCalendarModel *calendarItem = [[MSSCalendarModel alloc]init];
                calendarItem.year = 0;
                calendarItem.month = 0;
                calendarItem.day = 0;
                calendarItem.chineseCalendar = @"";
                calendarItem.holiday = @"";
                calendarItem.week = -1;
                calendarItem.dateInterval = -1;
                [resultArray addObject:calendarItem];
                continue;
            }
            components.day += 1;
            if(components.day == tatalDay + 1) // 本月數(shù)據(jù)循環(huán)結(jié)束
            {
                i = column;// 結(jié)束外層循環(huán)
                break;
            }
            MSSCalendarModel *calendarItem = [[MSSCalendarModel alloc]init];
            calendarItem.year = components.year;
            calendarItem.month = components.month;
            calendarItem.day = components.day;
            calendarItem.week = j;
            NSDate *date = [self componentsToDate:components];
            // 時(shí)間戳
            calendarItem.dateInterval = [self dateToInterval:date];
            if(_startDate == calendarItem.dateInterval)
            {
                _startIndexPath = [NSIndexPath indexPathForRow:0 inSection:section];
            }
            [self setChineseCalendarAndHolidayWithDate:components date:date calendarItem:calendarItem];
            
            [resultArray addObject:calendarItem];
        }
    }
    return resultArray;
}

價(jià)格日歷這塊,無非就是處理數(shù)據(jù)的時(shí)候加上了priceArray
@[ @{@"date":@"2018-09-08",@"price":@"238"}]


- (NSArray *)getJYCCalendarDataSoruceWithLimitMonth:(NSInteger)limitMonth type:(MSSCalendarViewControllerType)type calendarType:(MSSCalendarWithUserType)calendarType priceArray:(NSArray *_Nonnull)priceArray{
    
    NSMutableArray *resultArray = [[NSMutableArray alloc]init];
    NSMutableArray *priceMuArr = [NSMutableArray arrayWithArray:priceArray];
    
    NSDateComponents *components = [self dateToComponents:_todayDate];
    components.day = 1;
    if(type == MSSCalendarViewControllerNextType)
    {
        components.month -= 1;
    }
    else if(type == MSSCalendarViewControllerLastType)
    {
        components.month -= limitMonth;
    }
    else
    {
        components.month -= (limitMonth + 1) / 2;
    }
    NSInteger i = 0;
    for(i = 0;i < limitMonth;i++)
    {
        components.month++;
        MSSCalendarHeaderModel *headerItem = [[MSSCalendarHeaderModel alloc]init];
        NSDate *date = [self componentsToDate:components];
        [_dateFormatter setDateFormat: @"yyyy年MM月"];
        NSString *dateString = [_dateFormatter stringFromDate:date];
        headerItem.headerText = dateString;
        
        // 價(jià)格
        NSString *MMyue = [dateString substringWithRange:NSMakeRange(5, 2)];
        NSMutableArray *priArr = [NSMutableArray array];
        for (NSDictionary *dic in priceMuArr) {  // 從數(shù)據(jù)中選中當(dāng)月的數(shù)據(jù)
            NSString *da = [dic objectForKey:@"date"];
            if (da.length > 7) {
                NSString *mm = [da substringWithRange:NSMakeRange(5, 2)];
                if (MMyue == mm) {
                    [priArr addObject:dic];
                }
            }
        }
        [priceMuArr removeObjectsInArray:priArr];  // 移除選中月份的數(shù)據(jù)
        
        
        
        headerItem.calendarItemArray = [self getCalendarItemArrayWithDate:date section:i calendarType:calendarType withPriceArray:priArr];
        [resultArray addObject:headerItem];   
        
        if (calendarType == MSSCalendarSecnicType || calendarType == MSSCalendarAplaceType || calendarType == MSSCalendarActivityType) {
            if (priceMuArr.count <= 0) {    // 如果價(jià)格數(shù)據(jù)數(shù)組為空時(shí),不在展示以后的日歷
                break;
            }
        }
    }
    return resultArray;
}

找到第一天數(shù)據(jù)的具體時(shí)間,然后依次把數(shù)組中的數(shù)據(jù)賦值給第一天后的每一天(必須保證時(shí)間日歷的連續(xù)性)

        NSInteger priceTime = 0;
        if (priceArray.count > 0) {
            NSDictionary *dic = priceArray[0];
            NSString *ti = [dic objectForKey:@"date"];
            if (ti.length > 0) {
                priceTime = [self dateToInterval:[self dateFromString:ti]];
            }
        }

                // 時(shí)間戳
                NSInteger dateInterVal = [self dateToInterval:date];
                calendarItem.dateInterval = dateInterVal;
                if (priceTime == dateInterVal) {
                    indexB = 0;
                }
                if (indexB < priceArray.count) {
                    NSDictionary *dic = priceArray[indexB];
                    //                if (calendarType == MSSCalendarSecnicType) {
                    //                    calendarItem.price = [dic objectForKey:@"salePrice"];
                    //                }else if (calendarType == MSSCalendarAplaceType){
                    //                    calendarItem.userPrice = [dic objectForKey:@"userprice"];
                    //                    calendarItem.price = [dic objectForKey:@"webprice"];
                    //                }
                    calendarItem.price = [dic objectForKey:@"price"];
                    calendarItem.userInteractionEnabled = YES;
                }
                indexB++;

基地日歷:選擇一個(gè)開始時(shí)間后,后臺(tái)刷新日歷數(shù)據(jù),把最小時(shí)間以前和最大時(shí)間以后的數(shù)據(jù)全部設(shè)置為不可選 userInteractionEnabled = NO;

- (NSArray *)getCalendarDataSoruceWithMinNum:(NSInteger )minNum MaxNum:(NSInteger )maxNum startDate:(NSInteger )startDate endDate:(NSInteger )endDate andDataArray:(NSArray *)dataArray{
    
    NSMutableArray *daArr = [NSMutableArray array];
    [daArr addObjectsFromArray:dataArray];
    if (startDate > 0) {
        for (int i = 0; i < dataArray.count; i++) {
            MSSCalendarHeaderModel *headerItem = daArr[i];
            for (int j = 0; j < headerItem.calendarItemArray.count; j++) {
                
                MSSCalendarModel *model = headerItem.calendarItemArray[j];
                
                if (model.dateInterval == startDate) {
                    
                }
                if(model.dateInterval >= startDate + minNum*24*3600 && model.dateInterval <= startDate + maxNum*24*3600){
                    model.middleSelect = YES;
                    model.userInteractionEnabled = YES;
                    
                }else{
                    model.userInteractionEnabled = NO;
                }
            }
        }
    }

    if (endDate > 0  || startDate == 0) {
        for (int i = 0; i < dataArray.count; i++) {
            MSSCalendarHeaderModel *headerItem = daArr[i];
            for (int j = 0; j < headerItem.calendarItemArray.count; j++) {
                
                MSSCalendarModel *model = headerItem.calendarItemArray[j];
                if ([model.price floatValue] > 0) {
                    model.userInteractionEnabled = YES;
                    model.middleSelect = NO;
                }
            }
        }
    }
    
    return daArr;
    
}

詳見代碼,
代碼參考了一位大神,自己也封裝了業(yè)務(wù)需求。
GitHub項(xiàng)目地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,171評(píng)論 3 119
  • 告別 文||與你相識(shí) 你從自己的意識(shí)里離開 沒人要你做什么 你從自己的倔強(qiáng)里離開 沒有你的世界沒人哭泣 誰也不是誰...
    與你相識(shí)_40fa閱讀 104評(píng)論 0 2
  • 1小時(shí)后的七夕沒有人給你轉(zhuǎn)賬,你可以找我 你先把錢轉(zhuǎn)給我,我再轉(zhuǎn)給你,手續(xù)費(fèi)只抽2%,還配合換頭像,...
    海盜lucifer閱讀 166評(píng)論 0 0
  • 體驗(yàn)入:今天公司舉辦了中秋歡樂會(huì),負(fù)責(zé)策劃的5個(gè)人實(shí)在是太棒了,內(nèi)容很精彩,又感動(dòng)。先生還承諾了大家如果完成業(yè)績(jī)獎(jiǎng)...
    Tracy_zhang閱讀 119評(píng)論 0 4

友情鏈接更多精彩內(nèi)容