iOS Swift中自定义FSCalendar实现单日期多色标记的问题问询

实现方案(基于FSCalendar原生扩展,无需引入其他库)
方案1:自定义FSCalendarCell(推荐,性能更好,复用稳定)
- 新建继承自
FSCalendarCell的自定义Cell类,内部预置5个小圆点View,默认隐藏,固定布局在日期文本下方,小圆点尺寸建议设为4pt*4pt,圆角设为2pt,间距设为3pt - 调用
[FSCalendar registerClass: forCellReuseIdentifier:]注册你自定义的Cell类,替换默认Cell - 实现FSCalendar数据源方法
calendar:cellForDate:atMonthPosition:,根据当前日期对应的颜色标记数量,显示对应数量的小圆点,赋值对应背景色,多余的小圆点设为隐藏 - 调整FSCalendar的
appearance.cellHeight属性,给底部标记留出足够显示空间,避免标记被裁剪
方案2:快速实现(无需新建自定义类,直接在代理方法中添加Subview)
每次获取Cell时先清除旧的标记视图,再新增当前日期的标记,避免复用混乱,OC示例代码如下:
- (FSCalendarCell *)calendar:(FSCalendar *)calendar cellForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)monthPosition { FSCalendarCell *cell = [calendar dequeueReusableCellWithIdentifier:@"Cell" forDate:date atMonthPosition:monthPosition]; // 清除历史标记视图 [[cell.contentView.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UIView *view, NSDictionary *bindings) { return view.tag == 999; }]] makeObjectsPerformSelector:@selector(removeFromSuperview)]; // 读取当前日期对应的标记颜色数组 NSArray *colorList = [self fetchColorMarksForDate:date]; if (colorList.count == 0) return cell; // 新增标记容器 CGFloat dotSize = 4; CGFloat gap = 3; CGFloat containerWidth = colorList.count * dotSize + (colorList.count - 1) * gap; UIView *markContainer = [[UIView alloc] initWithFrame:CGRectMake((cell.contentView.bounds.size.width - containerWidth)/2, cell.contentView.bounds.size.height - 8, containerWidth, dotSize)]; markContainer.tag = 999; for (NSInteger i = 0; i < colorList.count; i++) { UIView *dot = [[UIView alloc] initWithFrame:CGRectMake(i*(dotSize + gap), 0, dotSize, dotSize)]; dot.backgroundColor = colorList[i]; dot.layer.cornerRadius = dotSize / 2; [markContainer addSubview:dot]; } [cell.contentView addSubview:markContainer]; return cell; }
Swift实现逻辑完全一致,仅需替换对应语法即可。
可选优化
如果需要支持标记点击、自定义形状等需求,可以在自定义Cell中添加对应的点击事件和属性配置,灵活度更高。
内容的提问来源于stack exchange,提问作者project ed500
相关产品推荐
相关产品推荐

