You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FSCalendar选中带事件日期后事件圆点消失且无法恢复问题求助

解决FSCalendar选中带事件日期后圆点消失的问题

这个问题我之前也碰到过,核心原因是你直接在willDisplay里手动修改cell的eventIndicator,但FSCalendar处理选中状态变化时,会重新渲染cell,这个过程并不会触发willDisplay方法,导致圆点的设置没有被重新执行;再加上cell复用机制的影响,就出现了圆点永久消失的情况。

最佳解决方案:使用官方数据源方法

FSCalendar本身提供了专门的数据源方法来管理事件圆点,这是框架推荐的实现方式,能自动处理所有状态变化(包括选中、切换月份、cell复用等场景),比手动修改cell可靠得多。

步骤如下:

  1. 确保你的ViewController遵守FSCalendarDataSource协议
  2. 实现calendar(_:numberOfEventsFor:)方法:
func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    let dateString = dateFormatter.string(from: date)
    
    // 检查当前日期是否存在事件
    for wp in worriesPanic {
        let wPDateStr = dateFormatter.string(from: wp.date!)
        if wPDateStr == dateString {
            return 1
        }
    }
    return 0 // 无事件时返回0
}
  1. 移除你原来在willDisplay里设置eventIndicator的代码,框架会自动根据这个方法的返回值,处理圆点的显示、隐藏以及选中状态下的渲染逻辑。

保留原有代码的修复方案

如果你因为特殊需求不想使用数据源方法,可以通过在选中/取消选中日期时强制刷新对应cell,来确保圆点重新设置:

  1. 先修改willDisplay方法,增加重置逻辑避免复用cell时的残留问题:
func calendar(_ calendar: FSCalendar, willDisplay cell: FSCalendarCell, for date: Date, at monthPosition: FSCalendarMonthPosition) { 
    let dateFormatter = DateFormatter() 
    dateFormatter.dateFormat = "yyyy-MM-dd" 
    let dateString = dateFormatter.string(from: date) 
    
    // 先重置事件数,避免复用cell时显示错误圆点
    cell.eventIndicator.numberOfEvents = 0
    cell.eventIndicator.isHidden = false
    
    for wp in worriesPanic{ 
        let wPDateStr = dateFormatter.string(from: wp.date!) 
        if wPDateStr == dateString { 
            cell.eventIndicator.numberOfEvents = 1 
            break 
        } 
    } 
}
  1. 实现didSelect和didDeselect方法,主动刷新对应cell:
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
    // 重新执行选中日期的圆点设置逻辑
    if let cell = calendar.cell(for: date, at: monthPosition) {
        calendar(calendar, willDisplay: cell, for: date, at: monthPosition)
    }
}

func calendar(_ calendar: FSCalendar, didDeselect date: Date, at monthPosition: FSCalendarMonthPosition) {
    // 重新执行取消选中日期的圆点设置逻辑
    if let cell = calendar.cell(for: date, at: monthPosition) {
        calendar(calendar, willDisplay: cell, for: date, at: monthPosition)
    }
}

这样用户选中或取消选中日期时,会重新触发圆点的设置逻辑,确保圆点正常显示。

为什么原代码会出问题?

当你选中日期时,FSCalendar会修改cell的选中样式(比如背景色、文字颜色),这个重绘过程不会触发willDisplay方法,而你之前设置的eventIndicator会在重绘中被重置,导致圆点消失。使用官方数据源方法的话,框架会在所有状态变化时自动重新计算事件数,从根源上避免了这个问题。

内容的提问来源于stack exchange,提问作者G S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 15:17:42