Changing the Sorting in an NSFetchedResultsController on the fly

后端 未结 4 988
执笔经年
执笔经年 2020-12-25 14:34

I\'m trying to change the sorting in a NSFetchController on the fly, by some sort of segmented control. To either sort A->Z Z->A type thing.

What do I have to do to

4条回答
  •  情话喂你
    2020-12-25 15:27

    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.

提交回复
热议问题