核心数据和表格视图

时间:2012-10-28 11:01:50

标签: ios uitableview core-data nsfetchedresultscontroller

场景:

我有跟踪iOS应用程序的费用,我将费用明细视图控制器的费用存储到表格视图中,该视图显示费用列表以及类别和金额。

在桌面视图的顶部,是一个带有CALENDAR按钮的UIView,一个显示日期的UILabel文本(例如:2012年10月23日(星期日))和另外两个按钮。 按下日历按钮会打开一个包含当前日期的自定义日历,两个按钮用于相应地递减和递增日期。

我想根据核心数据实体“费用”中属性的日期来节省费用。

问题:假设我按下日历按钮并从那里选择一些随机日期,其下方的表视图应显示当天的特定费用。我的意思是我希望表格视图只显示特定日期的费用,如果我按下按钮增加日期或递减日期,表格视图应显示当天的费用。我正在使用NSFetchedResultsController和Core Data来节省开支。

关于如何实现这一目标的任何想法?这是FRC的代码。

-(NSFetchedResultsController *)fetchedResultsController

{

if(_fetchedResultsController != nil)
{
return _fetchedResultsController;
}

AppDelegate * applicationDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
NSManagedObjectContext * context = [applicationDelegate managedObjectContext];

NSFetchRequest * request = [[NSFetchRequest alloc]init];

[request setEntity:[NSEntityDescription entityForName:@"Money" inManagedObjectContext:context]];

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

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

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

[sortDescriptor1 release];

self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                  managedObjectContext:context
                                                                  sectionNameKeyPath:nil
                                                                           cacheName:nil];
self.fetchedResultsController.delegate = self;

[request release];

NSError *anyError = nil;

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

return _fetchedResultsController;
}

谢谢你们。

1 个答案:

答案 0 :(得分:0)

您必须使用具有适当设置NSFetchedResultsController的新NSFetchRequest创建新的NSPredicate

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date == %@)", dateToFilterFor];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Expense" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];

// ...

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"SomeCacheName"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

分配新的FRC后,别忘了拨打[self.tableView reloadData];

编辑: 您可以将谓词分配给NSFetchRequest,然后将其分配给fetchedResultsController。您可以将谓词视为过滤器。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date == %@)", dateToFilterFor];

如果通过调用[fetchRequest setPredicate:predicate];将其添加到获取请求中,则告诉获取的请求仅获取结果NSManagedObject的日期属性与您在谓词中提供的日期相匹配。这正是你想要的。

因此,如果您有一个在用户选择日期后调用的方法,您可以像这样修改它:

- (void)userDidSelectDate:(NSDate *)date
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];


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

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

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
    NSArray *sortDescriptors = @[sortDescriptor];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    // nil for section name key path means "no sections".
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
   aFetchedResultsController.delegate = self;

   //Here you replace the old FRC by this newly created
   self.fetchedResultsController = aFetchedResultsController;


   NSError *error = nil;
   if (![self.fetchedResultsController performFetch:&error]) {
     // Replace this implementation with code to handle the error appropriately.
     // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
   }

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


}

请注意,如果您不使用ARC(您应该使用ARC),则必须适当地释放已分配的对象。