我正在制作一个联系人应用程序App,我从AddressBook获取名称并将它们存储在Core数据中,并使用NSFetchedResultsController在表格上显示名称.但是,出现的第一个索引和部分是#后跟字母表.但是我想这样做就像在原生联系人应用程序中那样#sign应该到最后.
我使用了以下NSortDescriptor:
我使用了以下NSortDescriptor:
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@”fullName” ascending:YES ];
这里“fullName”是核心数据中的关键,它通过连接名字和姓氏来实现.
如果fullName不以字母开头,则section标识符是“fullName”的第一个字母,其section标识为#.
我搜索过它并在NSortDescriptor比较器中使用了NSDiacriticInsensitiveSearch,但它没有用.如果有人有任何想法,请告诉我.
这是我的代码:
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"];
这是排序描述符:
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sortName" ascending:YES];
[self sectionIdentifier:sortName]如果sortName以非字母开头,则此方法返回#,否则返回它开始的字母表.
newContact是实体的对象.
解决方法
您可以在实体中存储其他属性sortName,如果名称以字母开头则为fullName,否则为< C> fullName. < c取代;是一个比所有字母“更大”的固定字符.例如
NSString *special = @"\uE000"; if ("fullName starts with letter") sortName = fullName; else sortName = [special stringByAppendingString:fullName];
现在,您可以根据sortName进行排序,如果sortName以特殊字符开头,则节标识符将为“#”.
缺点是你必须存储一个额外的属性,优点是你可以继续使用一个获取的结果控制器(它只能使用持久属性进行排序).
更新:它实际上可以更轻松地完成.
创建新条目时,如果是字母,则将sectionIdentifier设置为名称的第一个字符,否则设置为特殊字符:
NSString *special = @"\uE000"; if ([[NSCharacterSet letterCharacterSet] characterIsMember:[contact.contactName characterAtIndex:0]]) { contact.sectionIdentifier = [contact.contactName substringToIndex:1]; } else { contact.sectionIdentifier = special; }
获取的结果控制器使用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];
现在,所有非字母条目都分组在最后一节中.最后一步是为最后一节显示正确的节标题#:
- (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; }