具有节名称的NSFetchedResultsController

时间:2012-11-09 04:20:17

标签: ios core-data nsfetchedresultscontroller nsfetchrequest

情景:

我有跟踪iOS应用程序的费用,我将费用从费用明细视图控制器存储到表视图(带有提取结果控制器),该视图显示费用列表以及类别,金额和日期。我的实体“Money”中有一个日期属性,它是费用或收入的父实体。

我的问题:

我想要的是基本上对给定的一周,一个月或一年的费用/收入进行分类,并将其显示为部分标题,例如:(10月1日至10月7日),它显示费用/收入根据特定周数量和相关的东西。在该视图中提供了两个按钮,如果我按下右键,它将使一周增加一周(2012年10月1日至10月7日现在显示2012年10月8日 - 10月15日),同样左按钮将减少一周一个星期。我在视图中也有两个段控件。我想要做的是按下“每周”的段控制,如果我按下另一段“类别” - 我将如何根据类别过滤掉每周的费用/收入?

我想在我的表格视图中显示两个部分(一个显示费用的日期,另一个显示格式的收入日期(2012年10月1日 - 2012年10月7日))。我怎么做到这一点?我写了一些伪代码,如果有人能告诉我如何完成上述操作,那就太棒了。

编辑 - FETCH控制器

- (void)userDidSelectStartDate:(NSDate *)startDate andEndDate:(NSDate *)endDate
{    
    AppDelegate * applicationDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext * context = [applicationDelegate managedObjectContext];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Money" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];

    [NSFetchedResultsController deleteCacheWithName:nil];

    //Here you create the predicate that filters the results to only show the ones with the selected date
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", startDate, endDate];
    [fetchRequest setPredicate:predicate];

    // Set the batch size to a suitable number.
     [fetchRequest setFetchBatchSize:20];

    // Edit the sort key as appropriate.

    NSSortDescriptor * sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"type" ascending:YES];

    NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES];

    NSSortDescriptor *sortDescriptor3 = [[NSSortDescriptor alloc] initWithKey:@"cat" ascending:YES];

    NSArray * descriptors = [NSArray arrayWithObjects:sortDescriptor1, sortDescriptor2, sortDescriptor3, nil];

    [fetchRequest setSortDescriptors:descriptors];
    [fetchRequest setIncludesSubentities:YES];
    [fetchRequest setResultType:NSManagedObjectResultType];

    if(_fetchedResultsController)
    {
          [_fetchedResultsController release]; _fetchedResultsController = nil;

    }
    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"type" cacheName:nil];

    _fetchedResultsController.delegate = self;

    NSError *anyError = nil;

    if(![_fetchedResultsController performFetch:&anyError])
    {
        NSLog(@"error fetching:%@", anyError);
    }

    [sortDescriptor1 release];
    [sortDescriptor2 release];
    [sortDescriptor3 release];

    [fetchRequest release];

     //Finally you tell the tableView to reload it's data, it will then ask your NEW FRC for the new data
    [self.dashBoardTblView reloadData];

}

编辑 - 获取控制器代表方法

- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller
{
     [self.dashBoardTblView beginUpdates];

}


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
       atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

   switch(type) {
    case NSFetchedResultsChangeInsert:
        [self.dashBoardTblView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                      withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeDelete:
        [self.dashBoardTblView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
                      withRowAnimation:UITableViewRowAnimationFade];
        break;
   }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath{

    switch(type) {
    case NSFetchedResultsChangeInsert:

        [self.dashBoardTblView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeDelete:

        [self.dashBoardTblView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeMove:

        [self.dashBoardTblView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                         withRowAnimation:UITableViewRowAnimationFade];
        [self.dashBoardTblView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                         withRowAnimation:UITableViewRowAnimationFade];


        break;

    case NSFetchedResultsChangeUpdate:
    {
        [self.dashBoardTblView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;
    }
  }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.dashBoardTblView endUpdates];
} 

1 个答案:

答案 0 :(得分:10)

要将“费用”/“收入”对象分组到不同的部分,您需要向type实体添加Money属性,例如Integer属性{费用为{1}},收入为0

要按类型(费用/收入)对表格视图部分进行排序,请使用1作为第一个排序描述符:

type

要按日期对每个部分中的条目进行排序,请使用NSSortDescriptor *s1 = [[NSSortDescriptor alloc] initWithKey:@"type" ascending:YES]; 作为第二个排序描述符:

date

最后,要将表格视图按类别分组,请使用NSSortDescriptor *s2 = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES]; NSArray *descriptors = [NSArray arrayWithObjects:s1, s2, nil]; [fetchRequest setSortDescriptors:descriptors]; 作为type

sectionNameKeyPath

这应该给出2个部分,第一部分包括所有费用,第二部分包括所有收入。

现在对于部分标题,您必须实现NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:type cacheName:nil]; (我希望我能做到这一点):

tableView:viewForHeaderInSection: