UITableView sectioned with sort order not sectioni

2019-08-29 13:37发布

问题:

So I am trying to get a UITableView to show a list of objects by section (thing.title), but list them in descending order by date.

The table is is split into sections, which are labeled correctly (section headers are the different thing titles).

But the objects in each section are only half correct. The objects in each section are listed in descending order, but some sections contain data that should be in other sections.

An example of what is happening:

<Header> Big Title Name
    <data><Big Title><id=1></data>
    <data><Big Title><id=4></data>
    **<data><Small Title><id=6></data>**   <-- should not be in this section


<Header> Small Title Name
    <data><Small Title><id=11></data>
    <data><Big Title><id=23></data>  <-- should not be in this section
    **<data><Small Title><id=66></data>**

Here is part of my code:

- (NSFetchedResultsController *)fetchedResultsController {

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

/*
 Set up the fetched results controller.
 */
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"AReads" inManagedObjectContext:[NSManagedObjectContext defaultContext]];
[fetchRequest setEntity:entity];

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

// Sort using the timeStamp property..
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

[fetchRequest setSortDescriptors:sortDescriptors];

// Use the sectionIdentifier property to group into sections.
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[NSManagedObjectContext defaultContext] sectionNameKeyPath:@"sessionTitle" cacheName:@"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

return fetchedResultsController;
}


- (NSString*) tableView:(UITableView *)tableView titleForHeaderInSection:  (NSInteger)section
{
//return [(Sessions*)[masterSessions objectAtIndex: section] title];
id <NSFetchedResultsSectionInfo> theSection = [[fetchedResultsController sections] objectAtIndex:section];



NSString *theTitle = [theSection name];


return theTitle;
}

回答1:

The key used as sectionNameKeyPath of a fetched results controller and the key used in the first sort descriptor must either be the same keys or generate the same relative ordering. So you cannot use sessionTitle as sectionNameKeyPath and a completely different key timeStamp as sort descriptor for the sections.

In your case, it is probably the best to use timeStamp as sectionNameKeyPath and in the sort descriptor. This will ensure that all entries are correctly grouped into sections.

To display the sessionTitle instead of the timeStamp in the section header, you can modify titleForHeaderInSection:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.controller sections] objectAtIndex:section];
    return [[[sectionInfo objects] objectAtIndex:0] sessionTitle];
}