Customize the Lunar and events - zhoupIT/ZPTextView GitHub Wiki

Customize the Lunar and events:

• Get Lunar, events, holidays, solar terms and other information, can be completed by NSCalendar and EventKit.

Appearance classification

1.The lunar calendar provider NSCalendar

•	Create the Lunar Calendar version of NSCalendar.
@property (strong, nonatomic) NSCalendar *chineseCalendar;
self.chineseCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierChinese];

The most commonly used public identifier is NSCalendarIdentifierGregorian, where NSCalendarIdentifierChinese is used to represent the lunar calendar.

• The method of obtaining the lunar date
NSInteger lunarDay = [self.chineseCalendar component:NSCalendarUnitDay fromDate:date];

LunarDay variable is the corresponding date object lunar date, such as 1 on behalf of the first day. But we usually do not show the Arabic numerals to the calendar, you need to convert.

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

LunarDayString variable is the current corresponding lunar string, such as the first day, second day, thirty and so on.

2.EventKit, provider of events, solar terms and holidays

EventKit can be read through the system calendar built-in events, the need for calendar privileges, but to avoid the search and the introduction of three lunar frame of trouble.

#import <EventKit/EventKit.h>
@property (strong, nonatomic) NSArray<EKEvent *> *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; // start date
        NSDate *endDate = self.maximumDate; // expiration date
        NSPredicate *fetchCalendarEvents = [store predicateForEventsWithStartDate:startDate endDate:endDate calendars:nil];
        NSArray<EKEvent *> *eventList = [store eventsMatchingPredicate:fetchCalendarEvents];
        NSArray<EKEvent *> *events = [eventList filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(EKEvent * _Nullable event, NSDictionary<NSString *,id> * _Nullable bindings) {
                return event.calendar.subscribed;
        }]];
        weakSelf.events = events;
    }];

Here eventList variable is the start date to end date startDate endDate all the events between, while the events variable contains only subscription events, such as the Spring Festival, Labor Day, Christmas, the summer solstice, excluding users in the system calendar to add their own events , Such as a person's birthday and so on.

In the system calendar of the emulator environment, there is no subscription event such as lunar, holiday, etc. Please run it under the real machine.

3.The Lunar script, the event displayed to the FSCalendar

Basic UI building please refer to the first Customize the appearance.

•	to achieve `-calendar: subtitleForDate`:

Set the subtitle for the corresponding date, the return value can be any NSString object.

- (NSString *)calendar:(FSCalendar *)calendar subtitleForDate:(NSDate *)date
{
    EKEvent *event = [self eventsForDate:date].firstObject;
    if (event) {
        return event.title; // vernal equinox, Autumnal Equinox, Children's Day, Arbor Day, National Day, Christmas ...
    }
    NSInteger day = [_lunarCalendar component:NSCalendarUnitDay fromDate:date];
    return _lunarChars[day-1]; // First, second, third ...
}
// All events for a date
- (NSArray<EKEvent *> *)eventsForDate:(NSDate *)date
{
    NSArray<EKEvent *> *filteredEvents = [self.events filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(EKEvent * _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
        return [evaluatedObject.occurrenceDate isEqualToDate:date];
    }]];
    return filteredEvents;
}

####Result:

To customize the date text, implement -calendar: titleForDate:. For example let the text of the day show today.

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

Add event dots, to achieve -calendar: numberOfEventsForDate:

- (NSInteger)calendar:(FSCalendar *)calendar numberOfEventsForDate:(NSDate *)date
{
    NSArray<EKEvent *> *events = [self eventsForDate:date];
    return events.count;
}
-calendar: numberOfEventsForDate: Method supports up to 3 dots. Use -calendar: imageForDate: can replace any image style, the return value for the UIImage object.

####Result:

Using `[calendar reloadData]` causes all data sources and styles to be reloaded for asynchronous loading.

FeedBack or Contact

⚠️ **GitHub.com Fallback** ⚠️