美文网首页
iOS自定义日历控件(数据是服务器返回)

iOS自定义日历控件(数据是服务器返回)

作者: block_smile | 来源:发表于2017-10-02 17:52 被阅读77次
项目中涉及到日期课表,需要使用日历控件,找了一些第三方的demo,由于需要根据服务器返回的数据来显示日历的详情,所以都不太合适,就自己动手写了一个和大家分享.
  • 首先使用collectionView实现轮播效果,轮播器的实现在我之前的iOS无限轮播器中可以找到,直接使用即可.
  • 月份和week的建立,日历大家都很熟悉,一个月可能显示的星期数是不固定的,分为三种情况,每月可能需要显示的行数为4/5/6.服务器返回的数据结构是嵌套数组,第一层数组为一个月的星期数,第二层为每一个星期的天数,第二层数组每个数组的count均为7,返回的数据里可以判断是否是当月的日期.

代码:

  • 获取数据转换为模型.
 - (void)loadCalenderData {
    //获取当前月的第一天零时刻时间戳
    NSArray *firstDayArray = [self getFirstAndLastDayOfThisMonth];
    NSDate *firstDay = firstDayArray.firstObject;
    NSTimeInterval time = [firstDay timeIntervalSince1970];

    NSString *tokens = [kUserDefaults objectForKey:saveCompleteToken];
    FXNetwork *net = [[FXNetwork alloc]init];
    NSString *usrds = OCSTR(@"%@?month_time=%f",Teacher_Calender_GetCourseData,time);

    [net requsetWithUrl:usrds withToken:tokens withParams:nil withCacheType:FXClientReloadIgnoringLocalCacheData withRequestType:NetworkGetType withResult:^(id responseObject, NSError *error) {
          if (!error) {
            if ([[responseObject objectForKey:@"code"]integerValue] == 0) {
                NSLog(@"%@",responseObject);
                NSArray *tempTotalArray = [[responseObject objectForKey:@"data"] objectForKey:@"items"];
            
                for (int i = 0; i < tempTotalArray.count; i++) {
                
                    NSArray *tempArray = tempTotalArray[i];
                    NSMutableArray *temp1 = [NSMutableArray array];
                    for (int j = 0; j < tempArray.count; j++) {
                        NSDictionary *dict = tempArray[j];
                        FXCalenderModel *model = [FXCalenderModel yy_modelWithDictionary:dict];
                        [self.calenderRowArray addObject:model];
                        [temp1 addObject:model];
                }
                    [self.calenderTotalArray addObject:temp1];
                }
            
                NSString *timestr = [[responseObject objectForKey:@"data"] objectForKey:@"month_time"];
                self.currentMonthStr = [NSString getYearAndMonthStringWithTimestamp:[timestr doubleValue]];
            
                self.labMonth.text = self.currentMonthStr;
            
                [self.circleView reloadData];
                self.circleView.contentOffset = CGPointMake(SCREEN_WIDTH * 3 * kseed , 0);
            } else {
                [self showAlert:[responseObject objectForKey:@"message"] andDisAppearAfterDelay:2.0];
            }
        }
    }];
}
  • 下一月

      - (void)nexMonth {
      [self showLoadingViewWithMessage:@"加载数据中..."];
      [self.view addSubview:self.loadingView];
      NSDate *nextMonth = [self.gregorian dateByAddingUnit:NSCalendarUnitMonth value:1 toDate:self.currentMonth options:0];
      self.currentMonth = nextMonth;
    
      NSTimeInterval time = [self.currentMonth timeIntervalSince1970];
    
      NSString *tokens = [kUserDefaults objectForKey:saveCompleteToken];
      FXNetwork *net = [[FXNetwork alloc]init];
      NSString *usrds = OCSTR(@"%@?month_time=%f",Teacher_Calender_GetCourseData,time);
    
      [net requsetWithUrl:usrds withToken:tokens withParams:nil withCacheType:FXClientReloadIgnoringLocalCacheData withRequestType:NetworkGetType withResult:^(id responseObject, NSError *error) {
      if (!error) {
          NSLog(@"%@",responseObject);
          if ([[responseObject objectForKey:@"code"]integerValue] == 0) {
              
              [self.calenderTotalArray removeAllObjects];
              NSArray *tempTotalArray = [[responseObject objectForKey:@"data"] objectForKey:@"items"];
              
              for (int i = 0; i < tempTotalArray.count; i++) {
                  
                  NSArray *tempArray = tempTotalArray[i];
                  NSMutableArray *temp1 = [NSMutableArray array];
                  for (int j = 0; j < tempArray.count; j++) {
                      NSDictionary *dict = tempArray[j];
                      FXCalenderModel *model = [FXCalenderModel yy_modelWithDictionary:dict];
                      [self.calenderRowArray addObject:model];
                      [temp1 addObject:model];
                  }
                  [self.calenderTotalArray addObject:temp1];
              }
              
              NSString *timestr = [[responseObject objectForKey:@"data"] objectForKey:@"month_time"];
              self.currentMonthStr = [NSString getYearAndMonthStringWithTimestamp:[timestr doubleValue]];
              
              self.labMonth.text = self.currentMonthStr;
              
              if (self.calenderTotalArray.count == 6) {
                  [self.circleView mas_updateConstraints:^(MASConstraintMaker *make) {
                      make.height.offset(SCREEN_WIDTH / 7 * 6);
                  }];
                  self.layout.itemSize = CGSizeMake(SCREEN_WIDTH, SCREEN_WIDTH / 7 * 6);
              } else {
                  [self.circleView mas_updateConstraints:^(MASConstraintMaker *make) {
                      make.height.offset(SCREEN_WIDTH / 7 * 5);
                  }];
                  self.layout.itemSize = CGSizeMake(SCREEN_WIDTH, SCREEN_WIDTH / 7 * 5);
              }
              
              self.circleView.contentOffset = CGPointMake(SCREEN_WIDTH * 3 * kseed , 0);
              [self.circleView reloadData];
              [self.loadingView removeFromSuperview];
              [self hideLoadingView];
          } else {
              [self showAlert:[responseObject objectForKey:@"message"] andDisAppearAfterDelay:2.0];
          }
      }
      }];
    }
    
  • 上一月数据

    - (void)previousMonth {
      [self showLoadingViewWithMessage:@"加载数据中..."];
      [self.view addSubview:self.loadingView];
      NSDate *previousMonth = [self.gregorian dateByAddingUnit:NSCalendarUnitMonth value:-1 toDate:self.currentMonth options:0];
      self.currentMonth = previousMonth;
    
      NSTimeInterval time = [self.currentMonth timeIntervalSince1970];
    
      NSString *tokens = [kUserDefaults objectForKey:saveCompleteToken];
      FXNetwork *net = [[FXNetwork alloc]init];
      NSString *usrds = OCSTR(@"%@?month_time=%f",Teacher_Calender_GetCourseData,time);
    
      [net requsetWithUrl:usrds withToken:tokens withParams:nil withCacheType:FXClientReloadIgnoringLocalCacheData withRequestType:NetworkGetType withResult:^(id responseObject, NSError *error) {
          if (!error) {
              NSLog(@"%@",responseObject);
              if ([[responseObject objectForKey:@"code"]integerValue] == 0) {
              
                  [self.calenderTotalArray removeAllObjects];
                  NSArray *tempTotalArray = [[responseObject objectForKey:@"data"] objectForKey:@"items"];
              
                  for (int i = 0; i < tempTotalArray.count; i++) {
                  
                      NSArray *tempArray = tempTotalArray[i];
                      NSMutableArray *temp1 = [NSMutableArray array];
                      for (int j = 0; j < tempArray.count; j++) {
                          NSDictionary *dict = tempArray[j];
                          FXCalenderModel *model = [FXCalenderModel yy_modelWithDictionary:dict];
                          [self.calenderRowArray addObject:model];
                          [temp1 addObject:model];
                      }
                      [self.calenderTotalArray addObject:temp1];
                  }
              
              NSString *timestr = [[responseObject objectForKey:@"data"] objectForKey:@"month_time"];
              self.currentMonthStr = [NSString getYearAndMonthStringWithTimestamp:[timestr doubleValue]];
              
              self.labMonth.text = self.currentMonthStr;
              
              if (self.calenderTotalArray.count == 6) {
                  [self.circleView mas_updateConstraints:^(MASConstraintMaker *make) {
                      make.height.offset(SCREEN_WIDTH / 7 * 6);
                  }];
                  self.layout.itemSize = CGSizeMake(SCREEN_WIDTH, SCREEN_WIDTH / 7 * 6);
              } else {
                  [self.circleView mas_updateConstraints:^(MASConstraintMaker *make) {
                      make.height.offset(SCREEN_WIDTH / 7 * 5);
                  }];
                  self.layout.itemSize = CGSizeMake(SCREEN_WIDTH, SCREEN_WIDTH / 7 * 5);
              }
              
              self.circleView.contentOffset = CGPointMake(SCREEN_WIDTH * 3 * kseed , 0);
              [self.circleView reloadData];
              [self.loadingView removeFromSuperview];
              [self hideLoadingView];
          } else {
              [self showAlert:[responseObject objectForKey:@"message"] andDisAppearAfterDelay:2.0];
          }
      }
     }];
    }
    
  • 日历控件的父视图

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
        FXCircleViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellId" forIndexPath:indexPath];
        cell.calenderTotalArray = self.calenderTotalArray;
        cell.delegate = self;
        return cell;
    }
    
  • FXCircleViewCell自定义的cell

    //日历视图
    - (UICollectionView *)calenderView {
        if (!_calenderView) {
          UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
          _calenderView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:layout];
          layout.itemSize = CGSizeMake(SCREEN_WIDTH/7, SCREEN_WIDTH/7);
          layout.minimumLineSpacing = 0;
          layout.minimumInteritemSpacing = 0;
           _calenderView.dataSource = self;
          _calenderView.delegate = self;
         [_calenderView registerClass:[FXCalenderCell class] forCellWithReuseIdentifier:calenderViewCellId];
          _calenderView.backgroundColor = [UIColor whiteColor];
      }
      return _calenderView;
    }
    
    //创建视图
    -(void)setupUI{
    
      [self.contentView addSubview:self.calenderView];
      [self.calenderView mas_makeConstraints:^(MASConstraintMaker *make) {
          make.edges.offset(0);
      }];
    }
    
     //组数 5/6
    
     - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
        return self.calenderTotalArray.count;
    }
    
    //行数
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
        return 7;
    }
    
    //自定义日历cell FXCalenderCell
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
        FXCalenderCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:calenderViewCellId forIndexPath:indexPath];
        FXCalenderModel *model = (FXCalenderModel *)self.calenderTotalArray[indexPath.section][indexPath.row];
    
        //点击到上一月的日期对应状态的记录
        if (self.dayNum >= 24) {
          if (indexPath.section == self.calenderTotalArray.count - 1) {
            if ([model.day_num integerValue] == self.dayNum) {
              model.isDayNum = YES;
              self.dayNum = 0;
              self.cell = cell;
              self.model = model;
              }
            }
         }
    
      //当前日期的记录
        if ([model.day_status isEqualToString:@"0"]) {
          model.isSelected = YES;
          //self.model = nil;
          self.cell = cell;
          self.model = model;
          self.today = [model.day_time integerValue];
          //
         if ([_delegate respondsToSelector:@selector(selectedCellWith:)]) {
          [_delegate selectedCellWith:indexPath];
          }
      
         } else {
          model.isSelected = NO;
        }
    
        //点击到下一月的日期的状态记录
        if (self.dayNum <= 6) {
            if (indexPath.section == 0) {
                if ([model.day_num integerValue] == self.dayNum) {
                    model.isDayNum = YES;
                    self.dayNum = 0;
                    self.cell1 = cell;
                    self.model1 = model;
                }
            }
            if ([model.day_status isEqualToString:@"0"]) {
                model.isSelected = NO;
            }
        }
        cell.model = model;
        cell.backgroundColor = [UIColor whiteColor];
        return cell;
    }
    
  • 选中的cell

    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
        NSLog(@"%ld-----%ld",indexPath.section,indexPath.item);
        FXCalenderCell *cell = (FXCalenderCell *)[collectionView cellForItemAtIndexPath:indexPath];
        FXCalenderModel *model = (FXCalenderModel *)self.calenderTotalArray[indexPath.section][indexPath.row];
        //点击到上一月或下一月的日期后调到对应月份和点击日期对应的课程
        if (indexPath.section == 0 && [model.day_num integerValue] >= 24) {
            self.dayNum = [model.day_num integerValue];
            if ([_delegate respondsToSelector:@selector(chooseMonthWith:)]) {
                [_delegate chooseMonthWith:self.dayNum];
            }
            if ([_delegate respondsToSelector:@selector(selectedCellWith:)]) {
                [_delegate selectedCellWith:indexPath];
            }
        } else if (indexPath.section==self.calenderTotalArray.count-1 &&[model.day_num integerValue]<=6) {
            self.dayNum = [model.day_num integerValue];
            if ([_delegate respondsToSelector:@selector(chooseMonthWith:)]) {
                [_delegate chooseMonthWith:self.dayNum];
            }
            if ([_delegate respondsToSelector:@selector(selectedCellWith:)]) {
                [_delegate selectedCellWith:indexPath];
            }
        } else {
            if ([_delegate respondsToSelector:@selector(selectedCellWith:)]) {
                [_delegate selectedCellWith:indexPath];
            }
            //判断当月的状态
            if ([self.model.day_status isEqualToString:@"0"]) {
                self.cell.labCell.textColor = kUIColorFromRGB(0x00c6b9);
                self.cell.viewBg.hidden = YES;
                self.cell.point.backgroundColor = kUIColorFromRGB(0x68e1da);
          
                self.cell1.labCell.textColor = kUIColorFromRGB(0x333333);
                self.cell1.viewBg.hidden = YES;
                self.cell1.point.backgroundColor = kUIColorFromRGB(0xc1c1c1);
                self.cell1 = nil;
          
                cell.labCell.textColor = kUIColorFromRGB(0xffffff);
                cell.point.backgroundColor = kUIColorFromRGB(0xffffff);
                cell.viewBg.hidden = NO;
          
                self.cell = cell;
                self.model = model;
            } else if ([self.model.day_status isEqualToString:@"2"]){
          
                if ([self.model.day_time integerValue] > self.today) {
                    self.cell.labCell.textColor = kUIColorFromRGB(0x333333);
                    self.cell.viewBg.hidden = YES;
                    self.cell.point.backgroundColor = kUIColorFromRGB(0x68e1da);
              
                    self.cell1.labCell.textColor = kUIColorFromRGB(0x333333);
                    self.cell1.viewBg.hidden = YES;
                    self.cell1.point.backgroundColor = kUIColorFromRGB(0x68e1da);
                    self.cell1 = nil;
              
                } else if ([self.model.day_time integerValue] < self.today) {
                    self.cell.labCell.textColor = kUIColorFromRGB(0x333333);
                    self.cell.viewBg.hidden = YES;
                    self.cell.point.backgroundColor = kUIColorFromRGB(0xc1c1c1);
                }
          
          cell.labCell.textColor = kUIColorFromRGB(0xffffff);
          cell.point.backgroundColor = kUIColorFromRGB(0xffffff);
          cell.viewBg.hidden = NO;
          
          self.cell = cell;
          self.model = model;
          }
        }
    }
    
  • 数据的传递

    - (void)setCalenderTotalArray:(NSMutableArray *)calenderTotalArray {
        _calenderTotalArray = calenderTotalArray;
        [self.calenderView reloadData];
    }
    
  • 自定义FXCalenderCell

    -  自定义控件实现效果.
    
1 2

谢谢!

相关文章

网友评论

      本文标题:iOS自定义日历控件(数据是服务器返回)

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