EKRecurrenceRule(xcode iOS日历交互-Phonegap插件):帮助创建一个相当复杂的事件模式



我已经成功地修改了iPhone的Calendar.m和Calendar.h插件,以创建一个相当复杂的事件:

在给定的月份中,3周每7天发生一次事件,这个月的最后一周什么都没发生。

这一直有效,直到我意识到两件事:1.这是从开始日期开始的一个给定月份。开始日期可以是一个月中的任何地方,中间或结束或开始。2.并非所有月份都有28天。我必须解释29、30、31。3.结束日期和开始日期一样,也不一定是从月初或月底开始的。

我的EKRecurrenceRule语句:

EKRecurrenceRule* rrule = [[EKRecurrenceRule alloc] initRecurrenceWithFrequency:EKRecurrenceFrequencyMonthly
interval:1
daysOfTheWeek:nil
daysOfTheMonth:validDays monthsOfTheYear:nil weeksOfTheYear:nil daysOfTheYear:nil setPositions:nil end:rend];

我的有效天数数组(以当月天数为单位提供,如上)

//Note: 22 is week 4. This will be excluded. 
validDays = [[NSArray alloc]initWithObjects:
[NSNumber numberWithInt:1],
[NSNumber numberWithInt:8],
[NSNumber numberWithInt:15],
[NSNumber numberWithInt:29], nil];

EKAlarm btw为方便起见,偏移量为0。

是的,现在还很硬。我知道我必须更改validDays数组,我知道如何获得当天的日期编号,但我不知道从这里开始该怎么办。EKRecurrenceRule的文档似乎不包括从月初开始到月底结束的并发症。

至少在iOS7中,更改开始日期和结束日期似乎不会自动进行任何偏移。如果我从本月10日开始,f'rex,第一次提醒是在15日(8日和1日已经过去),而我希望在17日第一次提醒。第一次提醒应为自开始日期起7天,每次提醒后7天,每3周休息一周。

我目前的印象是,为了解决在月中开始以及月份长度不相等的问题,我可能需要创建多个EKRecurrenceRules,进而创建多个每周甚至每月的事件,这些事件不算作重复事件。这不是想要的结果,因为这样的事件很难在日历中删除。

有什么帮助吗?

第三次在这里回答我自己的问题。

编辑:我知道这个事件序列是针对一系列事件的,从一个月中的任意位置开始,直到结束日期,每月21天。稍后我将调整代码以匹配问题,但此解决方案与回答问题有关,包括限制

以下内容的有效期最长为1年。如果你决定使用这个超过1年,祝你好运,我真的无法计算出这样的东西,尤其是考虑闰年。

NSMutableArray *validDays = [[NSMutableArray alloc] init];
NSMutableArray *ignoreDays = [[NSMutableArray alloc] init];
//according to this algorithm, I only have 28 days a month. Even if a month has 31 or       30 or 29 days. This is because the schedule is counted by WEEK.
NSInteger currday = 1;
//excludeWeek denotes the week of a given month that I'll exclude, eg: 1 is the first week, 4 is the last week. This allows me to exclude any week of a given 28-day cycle. 
switch (excludeWeek)
{
case 1:
for (NSInteger i = 1; i <= 7; ++i)
{
[ignoreDays addObject:[NSNumber numberWithInt:i]];
}
break;
case 2:
for (NSInteger i = 8; i <= 14; ++i)
{
[ignoreDays addObject:[NSNumber numberWithInt:i]];
}
break;
case 3:
for (NSInteger i = 15; i <= 21; ++i)
{
[ignoreDays addObject:[NSNumber numberWithInt:i]];
}
break;
default: //or case 4:
for (NSInteger i = 22; i <= 28; ++i)
{
[ignoreDays addObject:[NSNumber numberWithInt:i]];
}
break; 
}
//this line here is why I can only guarantee results of 1 year. Anything more and endDay may very well be 1 day after startday. I'm using day of year, the only possible values are 1-365 or -1 to -365, +-1 for leap years. 
if (startDay == endDay) endDay -= 1;
while (startDay != endDay)
{
++startDay;
if (isLeapYear)
{
//Feb has 1 more day remember?
if (startDay > 366) startDay = 1;
}
else
{
if (startDay > 365) startDay = 1;
}

if ([ignoreDays containsObject:[NSNumber numberWithInteger:currday] ] == FALSE)
[validDays addObject: [NSNumber numberWithInt:startDay]];
++currday;
if (currday > 28) currday = 1;
}
EKRecurrenceRule* rrule = [[EKRecurrenceRule alloc]     initRecurrenceWithFrequency:EKRecurrenceFrequencyYearly
interval:1
daysOfTheWeek:nil
daysOfTheMonth:nil 
monthsOfTheYear:nil 
weeksOfTheYear:nil 
daysOfTheYear:[NSArray arrayWithArray:validDays] 
setPositions:nil end:rend];

希望任何人都不需要一个持续一年以上的复杂序列。使用这种方法,您应该知道如何以同样的方式填充一年中的几周。

这仍然会触发"请在单独的线程中运行"警告,但它比手动操作快得多。

最新更新