0

When sorting a table of objects from Core Data, I'd like to set a custom string for the section heading that includes an attribute. For example, I'd like the section name to display "4 Stars", instead of just 4. I've fiddle with it, but It seems to get grumpy if I try to set the string for the sectionNameKeyPath to anything other than an Entity Attribute and only an entity attribute. Here's what works for attribute only, and one of a few attempts to customize the string which breaks is commented out.

NSSortDescriptor *ratingDescriptor = [[NSSortDescriptor alloc] initWithKey:@"starRating" ascending:NO];
    sortDescriptors = [NSArray arrayWithObjects:ratingDescriptor, nameDescriptor, nil];
    [ratingDescriptor release], ratingDescriptor = nil;
    // NSString *starSectionHeading = [NSString stringWithFormat:@"%d Stars", @"starRating"];
    // sectionKeyPath = starSectionHeading;
sectionKeyPath = @"starRating";
DenVog
  • 4,226
  • 3
  • 43
  • 72

4 Answers4

1

The sectionNameKeyPath is supposed to be a key path i.e. the name of single attribute or the name of a relationship that terminates in a single attribute. You are trying to create a composite of two attributes and the FRC does not support that automatically.

To get something more fancy you will have to subclass NSFetchedResultsController. From the docs.

You create a subclass of this class if you want to customize the creation of sections and index titles. You override sectionIndexTitleForSectionName: if you want the section index title to be something other than the capitalized first letter of the section name. You override sectionIndexTitles if you want the index titles to be something other than the array created by calling sectionIndexTitleForSectionName: on all the known sections.

TechZen
  • 64,370
  • 15
  • 118
  • 145
1

Set your sectionNameKeyPath to the "starRating" but then modify the output in the table view. The FRC will sort things and tidy things up in sections you just have to change what you would normally display as the header string.

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{
    // Display the stars as section headings.
    int stars = [[[[fetchedResultsController sections] objectAtIndex:section] valueForKey:@"name"] intValue];
    if(stars == 1)
    {
        return @"1 Star"
    }
    else
    {
        return [NSString stringWithFormat:@"%u Stars", stars];
    }
}

I do this in some table views where the output format is handled in a generic fashion (I delegate the header titles to a another controller class given the first sort descriptor path and the value of the title). So you are not limited to hard coding the table view delegate methods like the above code.

You also get a chance to localize the string here as well, I have to deal with 15 localizations in my app and you have to think about things a bit differently when localizing.

Brent Priddy
  • 3,817
  • 1
  • 24
  • 16
0
(NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section
{
    if ([self.fetchedResultsController sections].count > 0) {
        id <NSFetchedResultsSectionInfo> sectionInfo = 
            [[self.fetchedResultsController sections] objectAtIndex:section];
        return [sectionInfo name];
    }
    return nil;
}
DrummerB
  • 39,814
  • 12
  • 105
  • 142
zzz
  • 1
0

Look at this answer with creating transient attribute: NSFetchedResultsController with sections created by first letter of a string

just change some names and in your version of committeeNameInitial replace:

[[self committeeName] substringToIndex:1];

with

[NSString stringWithFormat:@"%@ Stars", [self starRating]];
Community
  • 1
  • 1
alhcr
  • 823
  • 4
  • 12
  • 21