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

Swift 4中FSCalendar选中日期时事件点颜色被覆盖问题求助

解决FSCalendar选中日期时事件点变色的问题

Hey,这个问题我之前在用Swift项目集成FSCalendar的时候也踩过坑,给你两个亲测有效的解决思路:

方法一:利用FSCalendarDelegateAppearance代理强制指定事件颜色

FSCalendar默认会在日期选中时覆盖事件点的颜色,但我们可以通过实现FSCalendarDelegateAppearance的特定方法,给每个日期绑定固定的事件点颜色,完全不受选中状态影响。

首先让你的ViewController遵循该协议,然后实现以下方法:

extension YourViewController: FSCalendarDelegateAppearance {
    func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventDefaultColorsFor date: Date) -> [UIColor]? {
        // 替换成你自己的业务判断逻辑,区分绿色/红色事件日期
        if isGreenEventDate(date) {
            return [.green]
        } else if isRedEventDate(date) {
            return [.red]
        }
        // 无事件则返回nil
        return nil
    }
    
    // 辅助方法:判断日期是否对应绿色事件
    private func isGreenEventDate(_ date: Date) -> Bool {
        // 示例逻辑:比如今天显示绿色事件
        return Calendar.current.isDateInToday(date)
    }
    
    // 辅助方法:判断日期是否对应红色事件
    private func isRedEventDate(_ date: Date) -> Bool {
        // 示例逻辑:比如明天显示红色事件
        let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: Date())!
        return Calendar.current.isDate(date, inSameDayAs: tomorrow)
    }
}

同时别忘了实现事件数量的数据源方法,保证事件点能正常显示:

extension YourViewController: FSCalendarDataSource {
    func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
        return isGreenEventDate(date) || isRedEventDate(date) ? 1 : 0
    }
}

这个方法的核心是eventDefaultColorsForDate会直接为每个日期返回你指定的颜色,FSCalendar不会再用选中颜色去覆盖它,完美解决变色问题。

方法二:自定义FSCalendarCell控制事件点绘制

如果方法一在某些自定义场景下没生效,还可以直接子类化FSCalendarCell,手动接管事件点的颜色逻辑,忽略选中状态的影响。

先创建自定义Cell类:

import UIKit
import FSCalendar

class CustomCalendarCell: FSCalendarCell {
    override func configureAppearance() {
        super.configureAppearance()
        // 初始化时就设置事件点颜色
        updateEventIndicatorColor()
    }
    
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // 选中状态变化后,重新绑定事件点颜色
        updateEventIndicatorColor()
    }
    
    override func setHighlighted(_ highlighted: Bool, animated: Bool) {
        super.setHighlighted(highlighted, animated: animated)
        // 高亮状态变化后也重新设置(可选,按需开启)
        updateEventIndicatorColor()
    }
    
    private func updateEventIndicatorColor() {
        // 取第一个事件颜色(多事件点场景可扩展逻辑)
        self.eventIndicatorView.backgroundColor = self.eventColors?.first ?? .clear
    }
}

然后在ViewController里注册这个自定义Cell:

override func viewDidLoad() {
    super.viewDidLoad()
    // 注册自定义Cell
    calendar.register(CustomCalendarCell.self, forCellReuseIdentifier: "CustomCalendarCell")
    // 绑定其他代理和数据源...
}

这样不管单元格是选中还是高亮状态,事件点都会保持你设置的绿色或红色,不会被默认选中颜色替换。

内容的提问来源于stack exchange,提问作者Swift guy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:21:54