Implementation code of ebalendarview, an IOS simple calendar control

Time:2020-2-25

This paper introduces the implementation code of ebcalendarview, a simple calendar control of IOS, and shares it with you as follows:

Ebcalendarview calendar control, easy to call, simple code.

GitHub address: https://github.com/woheduole/ebcalendarview

Design sketch

Example of invocation

EBCalendarView *calendarView = [[EBCalendarView alloc] initWithFrame:CGRectMake(0, 64, CGRectGetWidth(self.view.bounds), 0)];
  calendarView.delegate = self;
  //calendarView.maxLastMonths = 0; 
  //calendarView.maxNextMonths = 0;
  [self.view addSubview:calendarView];
- (void)calendarView:(EBCalendarView*)calendarView didSelectedDate:(NSDate*)date {
  Nslog (@ "selected date:% @", [date stringwithformat: @ "yyyy MM DD");
}

Code directory

thinking

EBCalendarView


_collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.flowLayout];
    _collectionView.dataSource = self;
    _collectionView.delegate = self;
    _collectionView.showsVerticalScrollIndicator = NO;
    _collectionView.showsHorizontalScrollIndicator = NO;
    _collectionView.backgroundColor = [UIColor whiteColor];
    [_collectionView registerClass:[EBCalendarDayCell class] forCellWithReuseIdentifier:kEBCalendarViewReuseIdentifier];
Copy codeThe code is as follows:
_flowLayout.itemSize = CGSizeMake(viewWidth / kEBCalendarViewCellColumn, kEBCalendarViewCellHeight);

Use the uicollectionview control to display date data. Set the itemsize of uicollectionviewflowlayout. The height can be fixed. The width is removed by 7 with the total width of the view.

//Decimal rounding up
  NSInteger rows = ceilf(_dates.count / kEBCalendarViewCellColumn);
  self.frame = ({
    CGRect frame = self.frame;
    frame.size.height = kEBCalendarViewWeekViewHeight + kEBCalenderNavigationViewHeight + (rows * kEBCalendarViewCellHeight);
    frame;
  });

When switching months, because the week of the first day of each month is inconsistent, the number of lines will be different. For example, a month is 31 days, and its first day is Sunday. At this time, the date will have 6 lines. If its first day is Monday, it will display 5 lines. Here, it will dynamically change its height according to the number of lines.


- (NSDate *)dateByAddingMonths:(NSInteger)months {
  NSCalendar *calendar = [NSCalendar currentCalendar];
  NSDateComponents *components = [[NSDateComponents alloc] init];
  [components setMonth:months];
  return [calendar dateByAddingComponents:components toDate:self options:0];
}

When adding or subtracting months, increase the number of months directly through the nscalendar class, so that you don’t have to deal with the operation of clicking next month to 2019-01 in 2018-12 or clicking last month to 2018-12 in 2019-01.

Ebcalendarmodel data model

@property (nonatomic, assign) NSInteger year;
@property (nonatomic, assign) NSInteger month;
@property (nonatomic, assign) NSInteger day;
//Record selected status
@property (nonatomic, assign, getter=isSelected) BOOL selected;
//Is it the same day
@property (nonatomic, assign, getter=isToday) BOOL today;
//Convert year, month, day to nsdate
@property (nonatomic, strong, readonly) NSDate *date;
- (NSDate*)date {
  if (_year == 0 || _month == 0 || _day == 0) {
    return nil;
  }
  return [NSDate dateWithString:[NSString stringWithFormat:@"%zd-%zd-%zd"
              , _year
              , _month
              , _day] format:@"yyyy-MM-dd"];
}

Weekly view of ebcalenderweekview


- (void)layoutSubviews {
  [super layoutSubviews];
  [self createWeekView];
}

- (void)setWeeks:(NSArray *)weeks {
  _weeks = weeks;
  [self createWeekView];
}

- (void)createWeekView {
  CGFloat viewWidth = CGRectGetWidth(self.bounds)
  , viewHeight = CGRectGetHeight(self.bounds);
  if (_weeks.count == 0 || viewHeight == 0) return;
  [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
  NSInteger weekCount = _weeks.count;
  CGFloat weekWidth = viewWidth / weekCount;
  for (int n = 0; n < weekCount; n ++ ) {
    NSString *week = _weeks[n];
    UILabel *weekLabel = [[UILabel alloc] initWithFrame:CGRectMake(weekWidth * n, 0, weekWidth, viewHeight)];
    weekLabel.font = [UIFont systemFontOfSize:14];
    weekLabel.textColor = [UIColor colorWithHexString:@"333333"];
    weekLabel.textAlignment = NSTextAlignmentCenter;
    weekLabel.text = week;
    [self addSubview:weekLabel];
  }
}

Dynamically add uilabel to display weekly data according to the passed in parameter weeks.

Ebcalendernavigationview monthly Navigation view

- (void)changeMonthAction:(UIButton*)button {
  BOOL isNextMonth = NO;
  if ([button isEqual:_nextMonthButton]) {
    // next month
    isNextMonth = YES;
  }
  if ([self.delegate respondsToSelector:@selector(calenderNavigationViewDidChangeMonth:isNextMonth:)]) {
    [self.delegate calenderNavigationViewDidChangeMonth:self isNextMonth:isNextMonth];
  }
}

The left and right arrows and the middle month and year display are mainly displayed here. The left and right arrows are two UI buttons. When clicking them, the action is transferred to the ebcalendarview view view through the agent.

Uicolor + ebadd color helper class


+ (UIColor *)colorWithHexString:(NSString *)hexString {
  NSScanner *scanner = [NSScanner scannerWithString:hexString];
  unsigned hexNum;
  if (![scanner scanHexInt:&hexNum]) return nil;
  return [UIColor colorWithRGBHex:hexNum];
}

+ (UIColor *)colorWithRGBHex:(UInt32)hex {
  int r = (hex >> 16) & 0xFF;
  int g = (hex >> 8) & 0xFF;
  int b = (hex) & 0xFF;
  
  return [UIColor colorWithRed:r / 255.0f
              green:g / 255.0f
              blue:b / 255.0f
              alpha:1.0f];
}

The color in the code is the hexadecimal color value, which is purely personal habit.

Nsdate + ebadd date auxiliary class

//This method comes from yykit
- (NSInteger)year;

//This method comes from yykit
- (NSInteger)month;

//This method comes from yykit
- (NSInteger)day;

//This method comes from yykit
- (NSInteger)weekday;

//This method comes from yykit
- (BOOL)isToday;

//How many days are there in the current month
- (NSUInteger)numberOfDaysInMonth;

//This method comes from yykit
- (NSString *)stringWithFormat:(NSString *)format;

//This method comes from yykit
- (NSDate *)dateByAddingMonths:(NSInteger)months;

//This method comes from yykit
+ (NSDate *)dateWithString:(NSString *)dateString format:(NSString *)format;

Summary: uicollectionview is a very powerful control. By rewriting the layout through uicollectionviewflowlayout, many cool functions can be realized. The calendar control here only sets the width and height of the item, which is a very basic use. Two points need to be noted: 1. The first day of each month belongs to the day of the week, and then set its starting position; 2. How many days are there in each month. Different app types will also lead to different actual rendering methods of calendar controls. The basic logic is the same, except for some subtle controls.

The above is the whole content of this article. I hope it will help you in your study, and I hope you can support developepaer more.