NSSortDescriptor问题

use*_*153 4 xcode core-data objective-c nsfetchedresultscontroller

我正在制作一个联系簿应用程序,我从AddressBook获取名称并将它们存储在Core数据中,并使用NSFetchedResultsController.However第一个索引在表格上显示名称,然后出现的部分为#,后跟字母表.但我想这样做就像是在原生联系人应用程序,即#index应该到最后.
我使用了以下内容NSortDescriptor:

sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"fullName"ascending:YES];

这里"fullName"是key通过连接名字和姓氏而产生的核心数据.如果fullName不是以字母开头,则节标识符是"fullName"的第一个字母,其节标识符是#.
我搜索了它并NSDiacriticInsensitiveSearchNSortDescriptor比较器中使用但它没有用.如果有人有任何想法,请告诉我.

这是我的代码:

NSString *special = @"\uE000";
if ([[self sectionName:contactName] isEqualToString:@"#"]) {                           
    sortName = [special stringByAppendingString:contactName];
}
else{
    sortName = contactName;
}
[newContact setValue:[self sectionIdentifier:sortName] forKey:@"sectionIdentifier"];
[newContact setValue:sortName forKey:@"sortName"];
Run Code Online (Sandbox Code Playgroud)

这是排序描述符:

sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sortName" ascending:YES];
Run Code Online (Sandbox Code Playgroud)

[self sectionIdentifier:sortName] 如果sortName以非字母开头,则此方法返回#,否则返回它开始的字母表.

newContact是实体的对象.

Mar*_*n R 6

您可以sortName在实体中存储其他属性,fullName如果名称以字母开头,则为其他属性<C>fullName.<C>是一个比所有字母"更大"的固定字符.例如

NSString *special = @"\uE000";
if ("fullName starts with letter")
    sortName = fullName;
else
    sortName = [special stringByAppendingString:fullName];
Run Code Online (Sandbox Code Playgroud)

现在您可以按照排序sortName,如果sortName以特殊字符开头,则节标识符将为"#" .

缺点是你必须存储一个额外的属性,优点是你可以继续使用一个获取的结果控制器(它只能使用持久属性进行排序).

更新:它实际上可以更轻松地完成.

创建新条目时,sectionIdentifier如果是字母,则设置为名称的第一个字符,否则设置为特殊字符:

NSString *special = @"\uE000";

if ([[NSCharacterSet letterCharacterSet] characterIsMember:[contact.contactName characterAtIndex:0]]) {
    contact.sectionIdentifier = [contact.contactName substringToIndex:1];
} else {
    contact.sectionIdentifier = special;
}
Run Code Online (Sandbox Code Playgroud)

获取的结果控制器用于sectionIdentifier对节进行分组和排序.每个部分中的条目按以下顺序排序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];
Run Code Online (Sandbox Code Playgroud)

现在,所有非字母条目都分组在最后一节中.最后一步是显示#最后一节的正确节标题:

- (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;
}
Run Code Online (Sandbox Code Playgroud)