2011-02-05 22 views
1

我有一段時間正在構建自己的日曆,因爲標準mac cal在佈局方面很糟糕。objective-c構建我自己的自定義日曆(nsarraycontroller觀察者問題)

我所做的是讓一個NSCollectionView擁有我所有的日期,然後在我的代碼中我將每個日期添加到一個數組控制器。

到目前爲止,所有的工作正常,卡爾正在顯示!

我SS到這裏看看:http://cl.ly/0Z3a2i12242b2d1m3Z1n

我增加了一個觀測到我的NSArrayController的知道,每當用戶點擊一個日期,這讓我發信息給我的父類,告訴它來更新我的在cal下的table-list。

我的觀察是這樣的:

//觀察我們的陣列 - (空)observeValueForKeyPath:(的NSString *)的keyPath ofObject:(ID)對象的變化:(NSDictionary的*)的變化範圍內:(無效*)背景{

if([keyPath isEqualTo:@"selectionIndexes"]) 
{ 
    if([[self.arrayController selectedObjects] count] > 0) 
    { 
     if ([[self.arrayController selectedObjects] count] == 1) 
     { 
      CalendarDate* obj = [[self.arrayController selectedObjects] objectAtIndex:0]; 

      if(obj.dateobj != nil) 
      { 
       if(obj.isOld) 
       { 
        self.currentMonth = [self moveMonth:(NSInteger)-1]; 
        self.selectedDate = obj.dateobj; 

        [self buildArrayController]; 
       } 
       else { 
        self.selectedDate = obj.dateobj; 
        [self callParent]; 
       } 
      } 
     } 
    } 
} 

}

我最大的問題是,當用戶按下此當月之前的日期(看SS,IAM談論變灰的日期),然後觀察被調用兩次我的數組發送回到2個月,IAM不知道如何counterfight這個,現在我一直在掙扎了好幾天..

我爲構建陣列控制器代碼如下所示:

- (void) buildArrayController { 

    NSLog(@"Building array controller"); 

    // remove observer, all objects and set selection to -1 
    [arrayController removeObserver:self forKeyPath:@"selectionIndexes"]; 
    [[self.arrayController content] removeAllObjects]; 
    [self.arrayController setSelectionIndex:-1]; 

    // getting current month 
    NSDateComponents *nowComps = [self.currentCal components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSWeekdayCalendarUnit) fromDate:self.currentMonth]; 

    // figure out how many days the current month have 
    NSRange daysInMonth = [self daysInMonth:self.currentMonth]; 

    // save current month int for later 
    int month = [nowComps month]; 

    // getting days to add before this month  
    NSDateComponents *weekdayComponents = [self.currentCal components:NSWeekdayCalendarUnit fromDate:self.currentMonth]; 
    int weekdaysToAdd = (([weekdayComponents weekday] == 1) ? 8 : [weekdayComponents weekday])-2; 

    // add days befroe the current month, ie when 1st day of month is on a wednesday f.ex. 
    NSDate* lastMonth = [self moveMonth:-1]; 
    NSRange daysInLastMonth = [self daysInMonth:lastMonth]; 
    NSDateComponents *lastMonthComps = [self.currentCal components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSWeekdayCalendarUnit) fromDate:lastMonth]; 
    for (int i2 = 0; i2 < weekdaysToAdd; i2++) 
    { 
     [lastMonthComps setDay:daysInLastMonth.length-weekdaysToAdd+i2+1]; 

     CalendarDate* obj = [[CalendarDate alloc] init]; 
     obj.dateobj = [self.currentCal dateFromComponents:lastMonthComps]; 
     obj.showDot = [coreEditor checkDate:[self.currentCal dateFromComponents:lastMonthComps]]; 
     obj.textColor = [NSColor lightGrayColor]; 
     obj.isOld = YES; 

     [self.arrayController addObject:obj]; 

     [obj release]; 
    } 

    // adding actually month dates 
    for (int i = 1; i < daysInMonth.length+1; i++) 
    { 
     [nowComps setDay:i]; 

     CalendarDate* obj = [[CalendarDate alloc] init]; 
     obj.dateobj = [self.currentCal dateFromComponents:nowComps]; 
     obj.showDot = [coreEditor checkDate:[self.currentCal dateFromComponents:nowComps]]; 

     [self.arrayController addObject:obj]; 

     [obj release]; 
    } 

    // add days after the current month 
    NSDate* nextMonthobj = [self moveMonth:1]; 
    NSDateComponents *nextMonthComps = [self.currentCal components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSWeekdayCalendarUnit) fromDate:nextMonthobj]; 
    for (int i3 = 1; i3 < 7-weekdaysToAdd+1; i3++) 
    { 
     [nextMonthComps setDay:i3]; 

     CalendarDate* obj = [[CalendarDate alloc] init]; 
     obj.dateobj = [self.currentCal dateFromComponents:nextMonthComps]; 
     obj.showDot = [coreEditor checkDate:[self.currentCal dateFromComponents:nextMonthComps]]; 
     obj.textColor = [NSColor lightGrayColor]; 
     obj.isOld = YES; 

     [self.arrayController addObject:obj]; 

     [obj release]; 
    } 

    // add observer for our array controller 
    [self.arrayController addObserver:self 
          forKeyPath:@"selectionIndexes" 
           options:NSKeyValueObservingOptionNew 
           context:nil]; 

    // now figure out what object should be selected 
    NSDateComponents *selectedComp = [self.currentCal components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSWeekdayCalendarUnit) fromDate:self.selectedDate]; 
    int selectedMonth = [selectedComp month]; 
    int selectedDay = [selectedComp day]-1; 

    if(selectedMonth == month) 
    { 
     [self.arrayController setSelectionIndex:selectedDay+weekdaysToAdd]; 
    } 
    else { 
     [self.arrayController setSelectionIndex:-1]; 
    } 
} 

完蛋了!有什麼建議麼?

(順便說一句,如果您有任何擡起頭來對我做出更好的代碼,請告訴我,這是我的第一個項目在Objective-C有史以來:))

更新 我的「感覺」它不是真的觀察員是問題,但不知何故,當我按CAL中的前一天日期和我的方法重建數組時,它有點重新發送/點擊下一個視圖時,項目更新,是不是使得senes?我可以臨時禁用集合視圖上的點擊事件嗎?

UPDATE2 好吧,我嘗試添加了collecitonview這

    self.selectedDate = obj.dateobj; 
        self.currentMonth = [self moveMonth:(NSInteger)-1]; 

        [self.collectionView setSelectable:NO]; 

        [self buildArrayController]; 

        [self.collectionView setSelectable:YES]; 

刪除selectiable,但它不工作,所以它必須是shomehow被調用兩次觀測..:T

回答

0

它看起來像你的觀察員將被調用兩次:

  • 用戶選擇新的日期,在curr月。這會導致「selectionIndexes」中的更改並導致您的觀察者方法被調用。
  • 在buildArrayController中,您將自己作爲觀察者移除,進行更改,然後以觀察者身份重新激活自己。在以觀察者的身份重新添加自己之後,可以在數組控制器上調用「setSelectionIndex」,這會導致第二次觀察回調。

在第二個回調函數中,obj.isOld將爲false,所以幸運的是,您不要輸入這個無限循環。嘗試將呼叫移至

[self.arrayController addObserver:self 
         forKeyPath:@"selectionIndexes" 
          options:NSKeyValueObservingOptionNew 
          context:nil]; 

到buildArrayController的最後。

+0

你好,我會試試這個 – 2011-09-04 12:50:12

相關問題