In the object, you can save an additional attribute sortName , which is fullName if the name begins with a letter, and <C>fullName otherwise. <C> is a fixed character that is "larger" than all letters. for instance
NSString *special = @"\uE000"; if ("fullName starts with letter") sortName = fullName; else sortName = [special stringByAppendingString:fullName];
Now you can sort according to sortName , and the section identifier will be "#" if sortName starts with a special character.
The disadvantage is that you need to keep an additional attribute, the advantage is that you can continue to use the selected result controller (which can only use persistent attributes for sorting).
UPDATE: Actually, this can be done a little easier.
When you create a new record, you set the sectionIdentifier for the first character of the name if it is a letter, and otherwise for the special character:
NSString *special = @"\uE000"; if ([[NSCharacterSet letterCharacterSet] characterIsMember:[contact.contactName characterAtIndex:0]]) { contact.sectionIdentifier = [contact.contactName substringToIndex:1]; } else { contact.sectionIdentifier = special; }
The result controller uses sectionIdentifier to group and sort sections. Entries in each section are sorted by contactName :
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Contact"]; NSSortDescriptor *sort1 = [NSSortDescriptor sortDescriptorWithKey:@"sectionIdentifier" ascending:YES selector:@selector(localizedStandardCompare:)]; NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:@"contactName" ascending:YES selector:@selector(localizedStandardCompare:)]; [request setSortDescriptors:@[sort1, sort2]]; self.frc = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.context sectionNameKeyPath:@"sectionIdentifier" cacheName:nil];
All non-letter entries are now grouped in the last section. The final step is to display the correct section title # for the last section:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { id <NSFetchedResultsSectionInfo> sectionInfo = [[self.frc sections] objectAtIndex:section]; NSString *title = [sectionInfo name]; if ([title isEqualToString:special]) title = @"#"; return title; }