objective-c - NSSortDescriptor 问题

标签 objective-c xcode core-data nsfetchedresultscontroller

我正在制作一个通讯录应用程序,我从地址簿中获取姓名并将它们存储在核心数据中,并使用 NSFetchedResultsController.However 在表格上显示姓名,第一个索引和部分是# 后跟字母。但我想像在 native 联系人应用程序中那样做,即#index 应该最后出现。
我使用了以下 NSortDescriptor:

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

这里的“fullName”是核心数据中的key,由名字和姓氏拼接而成。 如果fullName不以字母开头,则段标识符为“fullName”的第一个字母,其段标识符为#。
我已经搜索过它并在 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,节标识符将为“#”以特殊字符开头。

缺点是你必须存储一个额外的属性,优点是你可以继续使用一个fetched results controller(它只能使用持久属性进行排序)。

更新:实际上可以做得更容易一些。

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

NSString *special = @"\uE000";

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

获取的结果 Controller 使用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;
}

关于objective-c - NSSortDescriptor 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12800062/

相关文章:

xcode - SourceKitService 吃掉 Xcode 8.3.2 上的所有 CPU

iOS CorePlot如何安装

ios - -[UICollectionViewData validateLayoutInRect :] while embedding in parent controller 中的断言失败

ios - 将数据从 Swift View Controller 传递到 Objective-C View Controller

objective-c - 如何将图像 URL 保存到照片库并随后使用保存的图像

swift - 实体名称为零的核心数据实体

ios - 获取触摸位置的uiview

iphone - ButtonPressed 方法上的警告

ios - 如何将 UITextField 中的值与 CoreData 值进行比较

ios - 如何获取 PHAsset 的 URL?