Updating of the calendar’s view for given Changing Status
The MeStatusViewController needs to communicate with CalendarViewController whenever a user has changed status. We do this by notifications because we are communicating ViewController to ViewController in a MVC setting.
MeStatusViewController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
- (void)viewWillDisappear:(BOOL)animated { //dispatch a serial thread to update the status [[LogicSingleton sharedInstance] updateUserSettingsColumn:@"status" withValue:self.status usingEmail:APPDELEGATE.currentUser.email onUpdatedBlk:^void(BOOL updated, NSString *newValue) { ... ... if(updated){ ... ... //POST A NOTIFICATION to CalendarViewController. [[NSNotificationCenter defaultCenter] postNotificationName:UpdateCalendarViewNotification object:nil]; } }]; [super viewWillDisappear:animated]; } |
Once an update is notified by MeStatusViewController, we call CalendarViewcontroller’s updateCalendarView using previously saved period history.
CalendarViewcontroller
1 2 3 4 |
-(void)updateCalendarView { [self updateCalendarViewWithPeriodDates:self.periodHistoryArray]; } |
When we update the calendar, notice we get the status of the app. Hence we’ll either get “Period Tracking” or “Trying to Conceive”. We process the period dates according to either these status.
CalendarViewcontroller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
-(void)updateCalendarViewWithPeriodDates:(NSArray*)dates { if(dates) { ... ... self.periodHistoryArray = dates; //let's always retain the incoming array of periods self.status = [[LogicSingleton sharedInstance] getUserSettingsColumn:@"status" usingEmail:APPDELEGATE.currentUser.email]; if([self.status compare:@"Period Tracking"]==NSOrderedSame) { //process for period tracking, ONLY DISPLAY PERIODS self.periodProbabilities = [[PeriodProbabilities alloc] initWithFlowRangeArray:dates]; } else { //process for Trying to Conceive self.cycleProbabilities = [[CycleProbability alloc] initWithFlowRangeArray:dates]; .... .... .... [self.datePickerView reloadData]; [self.calendarDayView reloadData]; [self.calendarDayView scrollToItemAtIndex:365 animated:YES]; } else { } } |
iCarousel dates
The dates on the iCarousel, is calculated this way:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
for ( int i = 365; i > 0; i--) { //create date component and set month to 1 NSDateComponents *components = [[NSDateComponents alloc] init]; //[components setMonth:-1]; [components setDay: -i ]; //using existin calendar, add 1 month to date 'now' NSDate * dateToAdd = [calendar dateByAddingComponents:components toDate:now options:0]; DateInfo * dateInfoObj = [[DateInfo alloc] initWithDate:dateToAdd andProbability:0.0f]; [self.daysCarouselDictionary setValue:dateInfoObj forKey:[NSString stringWithFormat:@"%u", carouselIndex++]]; } |
component setDay to -365 and then uses dateByAddingComponents:toDate: will generate a NSDate 365 days prior to today.
For example, if today is 5/22/15, then the result would be 5/22/14
-364 5/23/14
-363 5/24/14
…all the way until we have one full year of nsdates from 5/23/14 to 5/22/15.
As each date is generated, we insert it into daysCarouselDictionary.
daysCarouselDictionary is used in iCarousel delegate methods for data display.
We generate 2 years of dates, where today is smack in the middle.
Hence continuing from previous example, we then generate a future year
1 5/24/15
2 5/25/15
….
365 5/22/16
Thus, that is how we fill the iCarousel with those perspective dates.
Coloring of the period dates
CalendarViewController.m
1 2 3 4 5 6 7 8 9 10 11 |
- (BOOL)datePickerView:(RSDFDatePickerView *)view shouldColorDate:(NSDate *)date { if([self.status compare:@"Period Tracking"]==NSOrderedSame) { return [self.periodProbabilities isDatePeriod:date]; } else { return [self.cycleProbabilities isDateFirstPeriod:date]; } } |