Changing the Sorting in an NSFetchedResultsController on the fly?

Instead of using your NSFetchedResultsController as your table view data source, create an NSArray that you set when the user changes sort order with your segmented control basing the array contents on the fetched results. Then just sort using standard array sorting. Something like this: (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; } So the sort descriptor I've used is called "name", but you would change this to the name of the field you want to sort by in the fetched results. Also, the items ivar I've referenced would be your new table view data source.

Your table view delegates would now be something like this: (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; } Not sure if this is the best way, but it should work.

Instead of using your NSFetchedResultsController as your table view data source, create an NSArray that you set when the user changes sort order with your segmented control basing the array contents on the fetched results. Then just sort using standard array sorting. Something like this: - (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; } So the sort descriptor I've used is called "name", but you would change this to the name of the field you want to sort by in the fetched results. Also, the items ivar I've referenced would be your new table view data source.

Your table view delegates would now be something like this: - (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; } Not sure if this is the best way, but it should work.

This method works really well. Thanks Matt. – Dimitris Nov 21 '09 at 21:15.

FetchRequest is a read-only property. The line of code in your post will not work. If you want to use a different fetch request, you'll need to replace your controller with a new NSFetchedResultsController.

Your table won't reload automatically. You'll need to send it a reloadData message some time after you've replaced the NSFetchedResultsController.

3 Although you can't create replace the fetchRequest property of the NSFetchedResultsController (it is read only), you CAN change the properties of the fetchRequest and re-fetch. This saves you from having to recreate the NSFetchedResultsController. – Corey Floyd Dec 29 '09 at 6:28 Is there any possibility to change the sectionNameKeyPath without creating a new NSFetchedResultsController?

– ComSubVie Feb 10 '10 at 17:21 The sectionNameKeyPath is a readonly property, so I think you would need to create a new NSFetchedResultsController. – Alex Feb 10 '10 at 18:08.

I was stuck with the same problem and I could fix it with just setting the sort descriptors on the FetchRequestController's FetchRequest, then execute a fetch (performFetch) and finally reload the data on the 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; This was the easiest way for me to deal with the change the sorting on the fly without dropping the FRC or do any other fancy object handling. I am not sure about the performance implications on that and it could have an impact if the set of rows in the table is huge.

Instead of using your NSFetchedResultsController as your table view data source, create an NSArray that you set when the user changes sort order with your segmented control basing the array contents on the fetched results. Then just sort using standard array sorting. So the sort descriptor I've used is called "name", but you would change this to the name of the field you want to sort by in the fetched results.

Also, the items ivar I've referenced would be your new table view data source.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions