当前位置: 移动技术网 > 移动技术>移动开发>IOS > iOS 简约日历控件EBCalendarView的实现代码

iOS 简约日历控件EBCalendarView的实现代码

2019年07月24日  | 移动技术网移动技术  | 我要评论

本文介绍了ios 简约日历控件ebcalendarview的实现代码,分享给大家,具体如下:

ebcalendarview日历控件,调用简单,代码简洁。

github地址:https://github.com/woheduole/ebcalendarview

效果图

调用示例

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(@"选中日期:%@", [date stringwithformat:@"yyyy-mm-dd"]);
}

代码目录

思路

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];

复制代码 代码如下:
_flowlayout.itemsize = cgsizemake(viewwidth / kebcalendarviewcellcolumn, kebcalendarviewcellheight);

通过uicollectionview控件去显示日期数据,设置uicollectionviewflowlayout的itemsize,高度可以固定,宽度就是用视图的总宽度去除以7。

// 小数向上取整
  nsinteger rows = ceilf(_dates.count / kebcalendarviewcellcolumn);
  self.frame = ({
    cgrect frame = self.frame;
    frame.size.height = kebcalendarviewweekviewheight + kebcalendernavigationviewheight + (rows * kebcalendarviewcellheight);
    frame;
  });

切换月份的时候,由于每月的1号所在星期是不一致的,会导致行数不一样,比如一个月是31天,它的1号是星期日,这时候日期会有6行,如果它的1号是星期一,那么它会显示5行,这里会根据行数去动态的改变其高度。

- (nsdate *)datebyaddingmonths:(nsinteger)months {
  nscalendar *calendar = [nscalendar currentcalendar];
  nsdatecomponents *components = [[nsdatecomponents alloc] init];
  [components setmonth:months];
  return [calendar datebyaddingcomponents:components todate:self options:0];
}

月份在累加或累减的时候,通过nscalendar类直接增加月数,这样就不用自己去处理2018-12点击下个月切换到2019-01或者2019-01点击上个月切换到2018-12的操作了。

ebcalendarmodel 数据模型

@property (nonatomic, assign) nsinteger year;
@property (nonatomic, assign) nsinteger month;
@property (nonatomic, assign) nsinteger day;
// 记录选中状态
@property (nonatomic, assign, getter=isselected) bool selected;
// 是否为当天
@property (nonatomic, assign, getter=istoday) bool today;
// 将year,month,day转换成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"];
}

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];
  }
}

根据传入的参数weeks动态添加uilabel显示周数据。

ebcalendernavigationview 月份导航视图

- (void)changemonthaction:(uibutton*)button {
  bool isnextmonth = no;
  if ([button isequal:_nextmonthbutton]) {
    // 下个月
    isnextmonth = yes;
  }
  if ([self.delegate respondstoselector:@selector(calendernavigationviewdidchangemonth:isnextmonth:)]) {
    [self.delegate calendernavigationviewdidchangemonth:self isnextmonth:isnextmonth];
  }
}

这里面主要就显示左右箭头和中间的年月显示,左右箭头是两个uibutton,在点击它们的时候通过代理把动作给传到ebcalendarview视图。

uicolor+ebadd 颜色辅助类

+ (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];
}

代码中颜色都是用的16进制的颜色值,纯属个人习惯。

nsdate+ebadd 日期辅助类

// 该方法来源自yykit
- (nsinteger)year;

// 该方法来源自yykit
- (nsinteger)month;

// 该方法来源自yykit
- (nsinteger)day;

// 该方法来源自yykit
- (nsinteger)weekday;

// 该方法来源自yykit
- (bool)istoday;

// 当前月有多少天
- (nsuinteger)numberofdaysinmonth;

// 该方法来源自yykit
- (nsstring *)stringwithformat:(nsstring *)format;

// 该方法来源自yykit
- (nsdate *)datebyaddingmonths:(nsinteger)months;

// 该方法来源自yykit
+ (nsdate *)datewithstring:(nsstring *)datestring format:(nsstring *)format;

小结:uicollectionview很强大的一个控件,通过uicollectionviewflowlayout去重写布局,可以实现很多酷炫的功能。这里的日历控件只是设置了item的宽高,属于很基础的使用。其中需要注意两点:1.每个月的1号是属于周几,然后去设置它的起始位置;2.每个月有多少天。app类型不一样也会导致日历控件实际呈现方式不一样,基本逻辑都一样,无非就是一些细微的控制。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网