3

设想:

我有一个费用跟踪 iOS 应用程序,我有一个名为“DashBoardViewController”的视图控制器(表格视图控制器 - 带有 FRC),它基本上可以对给定一周、一个月或一年的费用/收入进行分类,并将其显示为部分标题标题例如:(2012 年 10 月 1 日至 10 月 7 日),它根据特定的周或月或年显示费用/收入 ROWS 和相关内容。

我的问题:

我想要完成的是:

假设我在三个不同的日期(分别为 2012 年 11 月 11 日、11 月 14 日、11 月 16 日)保存了 3 项名为“汽车”的相同类别的新费用。

在我的视图控制器中,我想将该类别“自动”显示为表格视图中的一行,但它应该只显示为一行而不是三次,因为我保存了三项费用(类别为“自动”)并且总金额应该是加起来我节省的所有 3 项费用(针对该特定类别)。类似于以下屏幕截图。

在此处输入图像描述

我写了一些代码位,它给了我相同类别的三行,而不是我真正想要的(同一类别的一行),我不知道如何计算它们的总数?应该与此处的 NSPredicate 或获取的结果控制器相关。任何帮助将不胜感激。

- (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];

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

   NSPredicate *predicateDate = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", startDate, endDate];

// Edit the sort key as appropriate.

  typeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"type" ascending:YES]; // type refers to an expense or income.

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

  if(self.choiceSegmentedControl.selectedIndex == 0)  // UISegment Control for "Sorting Category"
  {
      NSPredicate *predicateCategory = [NSPredicate predicateWithFormat:@"cat == %@", @""];
                
      NSArray * subPredicates = [NSArray arrayWithObjects:predicateCategory, predicateDate, nil];
    
      NSPredicate * compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
    
      [fetchRequest setPredicate:compoundPredicate];

      choiceSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"cat" ascending:NO];
   }

   NSArray * descriptors = [NSArray arrayWithObjects:typeSortDescriptor, dateSortDescriptor, choiceSortDescriptor, nil];

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

   
   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);
  }

  __block double totalAmount = 0;

  [[self.fetchedResultsController fetchedObjects] enumerateObjectsUsingBlock: ^void (Money *money, NSUInteger idx, BOOL *stop) {
    
    totalAmount += [[money amount] doubleValue];
  }];

  [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];

  self.startDate = startDate;
  self.endDate = endDate;

}

我想使用 NSDictionaryResultType 但这给我使用的 FRC 带来了问题(对于部分名称,填充表格视图等)

我循环通过 FRC 的代码给了我总金额(收入和支出)但我想要每个类别的总金额(例如:类别“汽车”的总金额,“娱乐”类别的总金额)。请帮助我,我完全被困在这里。

4

1 回答 1

0

我不认为你可以按摩你的 FRC 来返回你需要的那种物体。NSPredicate 只是过滤要返回的对象类型,它不会从数据中创建新对象。

但是,您可以获取按日期过滤的货币对象,然后使用KVC 集合运算符从货币对象数组中计算数据,如下所示:

NSArray *moneyObjectsFilteredbyDate = [self.fetchedResultsController fetchedObjects]
NSArray *categoryStrings = [moneyObjectsFilteredbyDate valueForKeyPath:@"@distinctUnionOfObjects.cat"];
NSArray *sortedCategoryStrings = [categoryStrings sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

NSMutableArray *aggregatedDataObjects = [NSMutableArray array];
for (NSString *aCategoryString in sortedCategoryStrings) {
    NSPredictate *categoryPredicate = [NSPredicate predicateWithFormat:@"cat == %@", aCategoryString];
    NSArray *moneyWithThisCategory  = [moneyObjectsFilteredByDate filteredArrayUsingPredicate:categoryPredicate];
    NSNumber *sum = [moneyWithThisCategory valueForKeyPath:@"@sum.amount"];
    [aggregatedDataObjects addObject:@{@"category" : aCategoryString, @"sum" : sum, @"individualExpenses" : moneyWithThisCategory}];
} 

当然,您可以在配置表格单元格的方法中执行部分操作(例如计算总和本身),但我希望它能给您一个想法。但我不认为您可以使用 SQL 查询或类似形式的谓词来创建新的数据结构。

您可以做的其他事情:使类别成为您的核心数据模型的单个对象,并在moneyobjects 和Category 对象之间添加关系。然后你可以只获取类别对象。尽管您随后必须按日期过滤某个类别的费用。

于 2013-01-10T21:23:20.943 回答