0

我有一個由NSFetchedResultsController驅動的UITableView。我調用了一種方法來創建一個NSPredicate,用於過濾自今天起擁有時間戳的實體。在我的NSFetchedResultsController中,我應用謂詞。NSFetchedResultsController刷新UITableView條目沒有重新加載口吃

if (appDelegate.displayTodayOnly) { 
    [fetchRequest setPredicate:datePredicate]; 
} 

這一切都很好。但是,偶爾我需要查看「今天」之前的條目。我在桌子視圖上向下滑動,當它已經在桌子的開始處時。

-(void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 
    if (self.tableView.contentOffset.y<0) { 
     if (appDelegate.displayTodayOnly) { 
      [appDelegate setDisplayTodayOnly:NO]; 
      NSInteger resultsOffset = [[self.fetchedResultsController fetchedObjects] count]; 
      //[self.tableView beginUpdates]; 
      [__fetchedResultsController release]; 
      __fetchedResultsController=nil; 
      NSError *error; 
      if (![[self fetchedResultsController] performFetch:&error]) { 
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
       exit(-1); // Fail 
      } 
      //[self.tableView endUpdates]; 
      NSInteger fullCount = [[self.fetchedResultsController fetchedObjects] count]; 
      if (fullCount>resultsOffset) { 
       NSUInteger sect = [[self.fetchedResultsController sections] count]-2; 
       id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:sect]; 
       NSUInteger rows = [sectionInfo numberOfObjects]-1; 
       NSIndexPath *indexing = [NSIndexPath indexPathForRow:rows inSection:sect]; 
       NSLog(@"IndexPath = section:%d row:%d",sect,rows); 
       [self.tableView reloadData]; 
       [self performSelector:@selector(scrollToIndexPath:) withObject:indexing afterDelay:0.0001]; 
      } 
     } 
    } 
} 

這也適用,但不雅。它放棄fetchedResultsController,並從條目開始的時間開始重新加載表。然後,我將它滾動到上一個表的條目上方的索引路徑。

我想要發生的是要在當前表的頂部之前加載和插入條目。有誰知道一個優雅的方式來改變提取的發生?

回答

0

我發佈了我的解決方案,希望它可以幫助其他需要幫助的人。

我仍然將NSFetchedResultsController實例設置爲零,並獲取具有不同謂詞的新實例。然後,而不是重新加載表(導致迷失方向的跳轉),在for(循環)中,我手動調用[self.tableView insertSections:[NSIndexSet indexSetWithIndex:i] withRowAnimation:UITableViewRowAnimationNone];,該方法幾乎直接從<NSFetchedResultsControllerDelegate>方法的樣板controllerWillChangeContent:中取出。這是有效的,因爲最後一部分總是將成爲今天的部分。如果今天沒有任何條目,那麼我需要重新加載數據,因爲插入的部分數量不一致,因爲今天的空白部分算作部分。

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 
{ 
    if (self.tableView.contentOffset.y<0) { 
     if (appDelegate.displayTodayOnly) { 
      [appDelegate setTodayOnlyMemory:NO]; 
      NSUInteger resultsOffset = [[self.fetchedResultsController fetchedObjects] count]; 
      [__fetchedResultsController release]; 
      __fetchedResultsController = nil; 
      self.fetchedResultsController = nil; 

      NSError *error = nil; 
      if (![self.fetchedResultsController performFetch:&error]) 
      { 
       NSLog(@"error in fetched results controller of Memory Notes"); 
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
       abort(); 
      } 
      if (resultsOffset) { 
       [self.tableView beginUpdates]; 
       NSInteger afCount = ([[self.fetchedResultsController sections] count]-1); 
       for (NSInteger i=0; i<afCount; i++) { 
        [self.tableView insertSections:[NSIndexSet indexSetWithIndex:i] withRowAnimation:UITableViewRowAnimationNone]; 
       } 
       [self.tableView endUpdates]; 
      } else { 
       [self.tableView reloadData]; 
      }    
      [self performSelector:@selector(scrollToSpot) withObject:nil afterDelay:0.01f]; 
     } 
    } 
} 

此外,這裏是我的scrollToSpot方法結束在正確的位置。

-(void)scrollToSpot 
{  
    NSArray *sectArray = [self.fetchedResultsController sections]; 
    if ([sectArray count]>1) { 
     id <NSFetchedResultsSectionInfo> sectionInfo = [sectArray objectAtIndex:([sectArray count]-2)]; 
     NSInteger theRow = [sectionInfo numberOfObjects]-1; 
     NSIndexPath* ipath = [NSIndexPath indexPathForRow:theRow inSection:([sectArray count]-2)]; 
     NSLog(@"Row:%d",ipath.row); 
     [self.tableView scrollToRowAtIndexPath:ipath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
     NSLog(@"ContentOffset:%.0f",self.tableView.contentOffset.y); 
    } 
} 
1

我最常做的是設置

self.fetchedResultsController = nil; 

並重新加載。它非常高效並且代碼最少(假設您像在Xcode模板中一樣加載並創建提取的結果控制器)。

+0

是的,它的工作,這是我的scrollViewDidEndDragging方法發生了什麼。我試圖瞭解是否可能有一種方法來減輕重新加載,所以結果不會跳來跳去。 – JacobFennell 2012-02-07 16:49:12