19

我正在尝试通过某种分段控制动态更改 NSFetchController 中的排序。要么排序 A->Z Z->A 类型的东西。

我该怎么做才能做到这一点?我在这里遵循 Jeff Lamarche 的示例:这里

我需要创建一个新的 NSFetchedResultsController 然后设置它,还是我只是创建一个新的 NSFetchRequest 并执行

fetchedResultController.fetchRequest = newFetchRequest

然后我的表会自动更新?

4

4 回答 4

33

我遇到了同样的问题,我可以通过在 FetchRequestController 的 FetchRequest 上设置排序描述符来解决它,然后执行 fetch (performFetch),最后在 table view 上重新加载数据。

NSArray *sortDescriptors = [NSArray arrayWithObject: sorter];
[[fetchedResultsController fetchRequest] setSortDescriptors:sortDescriptors];
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
        // Handle you error here
}
[sorter release];
[myTableView reloadData];

这是我在不丢弃 FRC 或进行任何其他花哨的对象处理的情况下即时更改排序的最简单方法。我不确定这对性能的影响,如果表中的行集很大,它可能会产生影响。

于 2010-09-12T18:53:19.120 回答
7

不要使用您的 NSFetchedResultsController 作为您的表视图数据源,而是创建一个 NSArray,当用户使用基于获取的结果的数组内容更改您的分段控件更改排序顺序时设置它。然后只需使用标准数组排序进行排序。像这样的东西:

- (IBAction)segmentChanged:(id)sender
{
    // Determine which segment is selected and then set this 
    // variable accordingly
    BOOL ascending = ([sender selectedSegmentIndex] == 0);

    NSArray *allObjects = [fetchedResultsController fetchedObjects];

    NSSortDescriptor *sortNameDescriptor = 
                       [[[NSSortDescriptor alloc] initWithKey:@"name" 
                                 ascending:ascending] autorelease];

    NSArray *sortDescriptors = [[[NSArray alloc] 
                     initWithObjects:sortNameDescriptor, nil] autorelease];

    // items is a synthesized ivar that we use as the table view
    // data source.
    [self setItems:[allObjects sortedArrayUsingDescriptors:sortDescriptors]];

    // Tell the tableview to reload.
    [itemsTableView reloadData];    
}

因此,我使用的排序描述符称为“名称”,但您可以将其更改为要在获取的结果中排序的字段的名称。此外,我引用的项目 ivar 将是您的新表视图数据源。您的表视图代表现在将是这样的:

- (NSInteger)tableView:(UITableView*)tableView 
 numberOfRowsInSection:(NSInteger)section
{
    return [items count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Get your table cell by reuse identifier as usual and then grab one of
    // your records based on the index path
    // ...

    MyManagedObject *object = [items objectAtIndex:[indexPath row]];

    // Set your cell label text or whatever you want 
    // with one of the managed object's fields.
    // ...

    return cell;
}

不确定这是否是最好的方法,但它应该有效。

于 2009-11-11T22:51:15.460 回答
3

Andreas Schaefer 的回答对我有用。诀窍是为获取请求设置一个新参数,是否是此代码:

[[fetchedResultsController fetchRequest] setSortDescriptors:sortDescriptors];

或者

[[fetchedResultsController fetchRequest] setPredicate:predicate];

在调用这个之前:

if (![[self fetchedResultsController] performFetch:&error]) {
        // Handle you error here
}

[self.tableView reloadData];

看来,当您设置新参数时,NSFetchedResultsController 将根据您设置的内容执行新的 fetchrequest。如果不设置新参数,它将不会执行重新获取,并且仅调用performFetch它将不起作用..

希望这对其他人有帮助..

于 2014-01-30T04:50:08.873 回答
1

fetchRequest是一个只读属性。您帖子中的代码行将不起作用。如果你想使用不同的 fetch 请求,你需要用一个新的NSFetchedResultsController. 您的表格不会自动重新加载。您需要reloadData在更换NSFetchedResultsController.

于 2009-11-11T20:18:59.383 回答