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

时间:2013-12-26 10:26:26

标签: ios cordova calendar

我已成功修改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];

我的validDays数组(在上面的daysOfTheMonth中提供)

//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,并且通过扩展多个每周甚至每月不会计入的事件重复事件。这不是理想的结果,因为此类事件在日历中很难删除。

任何帮助?

1 个答案:

答案 0 :(得分:0)

第三次在这个地方回答我自己的问题。

编辑:我发现此事件序列适用于从一个月中的任意位置开始直到结束日期为止的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];

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

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