FSCalendar使用介绍(二) - 农历、事件

获取农历、事件、节假日、节气等信息,可以通过NSCalendarEventKit完成。

一. 农历提供者NSCalendar

  • 创建农历版NSCalendar。
@property (strong, nonatomic) NSCalendar *chineseCalendar;
self.chineseCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierChinese];

最常用的公立标识符是NSCalendarIdentifierGregorian, 此处使用NSCalendarIdentifierChinese表示农历。

  • 获取农历日期的方法
NSInteger lunarDay = [self.chineseCalendar component:NSCalendarUnitDay fromDate:date];

变量lunarDay即为date对象对应的农历日期,如1代表初一。但是我们通常不会将阿拉伯数字展示到日历,需要自己转换。

@property (strong, nonatomic) NSArray *lunarChars;
self.lunarChars = @[@"初一",@"初二",@"初三",@"初四",@"初五",@"初六",@"初七",@"初八",@"初九",@"初十",@"十一",@"十二",@"十三",@"十四",@"十五",@"十六",@"十七",@"十八",@"十九",@"二十",@"二一",@"二二",@"二三",@"二四",@"二五",@"二六",@"二七",@"二八",@"二九",@"三十"];
NSString *lunarDayString = self.lunarChars[day-1]; 

变量lunarDayString即为当前对应的农历字符串,如初一、初二、三十等。

二. 事件、节气、节假日提供者EventKit

通过EventKit可以读取系统日历的内置事件,需要日历权限,但避免了搜索和引入三方农历框架的麻烦。

#import 
@property (strong, nonatomic) NSArray *events;
__weak typeof(self) weakSelf = self;
EKEventStore *store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
    if(granted) {
        NSDate *startDate = self.minimumDate; // 开始日期
        NSDate *endDate = self.maximumDate; // 截止日期
        NSPredicate *fetchCalendarEvents = [store predicateForEventsWithStartDate:startDate endDate:endDate calendars:nil];
        NSArray *eventList = [store eventsMatchingPredicate:fetchCalendarEvents];
        NSArray *events = [eventList filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(EKEvent * _Nullable event, NSDictionary * _Nullable bindings) {
                return event.calendar.subscribed;
        }]];
        weakSelf.events = events;
    }];

此处eventList变量即为开始日期startDate到截止日期endDate之间的所有事件,而events变量只包含订阅事件,如春节、劳动节、圣诞节、夏至等,排除了用户在系统日历中自己添加的事件,如某某人的生日等。

模拟器环境的系统日历中没有包含农历、节假日等订阅事件,请在真机下运行。

三、将农历文字、事件展示到FSCalendar

基础的UI搭建请参考第一篇Hello World.

1、 实现-calendar:subtitleForDate:
为对应的日期设置副标题,返回值可以是任意NSString对象。

- (NSString *)calendar:(FSCalendar *)calendar subtitleForDate:(NSDate *)date
{
    EKEvent *event = [self eventsForDate:date].firstObject;
    if (event) {
        return event.title; // 春分、秋分、儿童节、植树节、国庆节、圣诞节...
    }
    NSInteger day = [_lunarCalendar component:NSCalendarUnitDay fromDate:date];
    return _lunarChars[day-1]; // 初一、初二、初三...
}

// 某个日期的所有事件
- (NSArray *)eventsForDate:(NSDate *)date
{
    NSArray *filteredEvents = [self.events filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(EKEvent * _Nullable evaluatedObject, NSDictionary * _Nullable bindings) {
        return [evaluatedObject.occurrenceDate isEqualToDate:date];
    }]];
    return filteredEvents;
}

效果:


FSCalendar使用介绍(二) - 农历、事件_第1张图片

若要自定义日期文字,实现-calendar:titleForDate:即可。例如让当日的文字显示今天

@property(strong, nonatomic) NSCalendar *gregorianCalendar;
self.gregorianCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
- (NSString *)calendar:(FSCalendar *)calendar titleForDate:(NSDate *)date
{
    if ([self.gregorianCalendar isDateInToday:date]) {
        return @"今天";
    }
    return nil;
}

3、添加事件圆点, 实现-calendar:numberOfEventsForDate:

- (NSInteger)calendar:(FSCalendar *)calendar numberOfEventsForDate:(NSDate *)date
{
    NSArray *events = [self eventsForDate:date];
    return events.count;
}

-calendar:numberOfEventsForDate:方法最大支持3个圆点。使用-calendar:imageForDate:可以代替为任意图片样式,返回值为UIImage对象。

效果:

FSCalendar使用介绍(二) - 农历、事件_第2张图片

使用[calendar reloadData]会使所有数据源及样式重新加载,适用于异步加载。

项目主页:https://github.com/WenchaoD/FSCalendar

QQ支持群: 323861692
FSCalendar使用介绍(二) - 农历、事件_第3张图片

你可能感兴趣的:(FSCalendar使用介绍(二) - 农历、事件)