首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSSortDescriptor问题

NSSortDescriptor问题
EN

Stack Overflow用户
提问于 2012-10-09 12:29:02
回答 4查看 2.8K关注 0票数 4

我正在制作一个联系人簿应用程序,我从AddressBook中获取名称,并将它们存储在核心数据中,并使用NSFetchedResultsController.However将名称显示在表上,出现的第一个索引和部分是#,后面跟着字母。但我想这样做,就像它是在本地联系应用程序,即#索引应该来最后。

我使用了以下NSortDescriptor

sortDescriptor = [NSSortDescriptor alloc initWithKey:@"fullName“上升:是];

在这里,"fullName“是核心数据中的key,它是通过将名字和姓氏连在一起生成的。节标识符是"fullName“的第一个字母,如果fullName不以字母表开头,则其节标识符为#。

我搜索过它并在NSortDescriptor比较器中使用了NSortDescriptor,但是它没有起作用。如果有人知道,那就告诉我。

下面是我的代码:

代码语言:javascript
复制
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"];

下面是排序描述符:

代码语言:javascript
复制
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sortName" ascending:YES];

[self sectionIdentifier:sortName]这个方法返回#如果sortName以非字母表开头,而另一个方法返回它开始时的字母表。

newContact是实体的对象。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-10-17 18:24:05

您可以在实体中存储一个附加属性sortName,如果名称以字母开头,则为fullName,而<C>fullName则为其他属性。<C>是一个固定的字符,它比所有的字母都“大”。例如

代码语言:javascript
复制
NSString *special = @"\uE000";
if ("fullName starts with letter")
    sortName = fullName;
else
    sortName = [special stringByAppendingString:fullName];

现在您可以根据sortName进行排序,如果sortName以特殊字符开头,则节标识符将为"#“。

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

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

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

代码语言:javascript
复制
NSString *special = @"\uE000";

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

获取的结果控制器使用sectionIdentifier对部分进行分组和排序。每个部分中的条目按contactName排序。

代码语言:javascript
复制
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];

所有非字母条目现在都在最后一节中分组。最后一步是为最后一节显示正确的节头#

代码语言:javascript
复制
- (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;
}
票数 6
EN

Stack Overflow用户

发布于 2012-10-12 19:58:56

您可以将结果分成两个数组,一个以alpha字符开头,另一个不以alpha字符开头,然后将这两个数组相加。假设您从一个名为results的托管对象数组开始

代码语言:javascript
复制
//Create the sort descriptor array
NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"fullName" ascending:YES];
NSArray *descriptors = [NSArray arrayWithObject:sd];

//Create a sorted array of objects where fullName starts with an alpha character
//using a Regex

NSPredicate *pred = [NSPredicate predicateWithFormat:@"fullName MATCHES '^[a-zA-Z].*'"];

NSArray *alpha = [[results filteredArrayUsingPredicate:pred] sortedArrayUsingDescriptors:descriptors];

//Now use the alpha array to create an array of objects where the fullName does not
//start with an alpha character

NSMutableArray *nonAlpha = [results mutableCopy];

[nonAlpha removeObjectsInArray:alpha];

[nonAlpha sortUsingDescriptors:descriptors];

//Now put them back together again

NSArray *sortedResults = [alpha arrayByAddingObjectsFromArray:nonAlpha];

//And if you're not using ARC!
[nonAlpha release];
票数 2
EN

Stack Overflow用户

发布于 2012-10-09 12:56:02

你可以这样做:

代码语言:javascript
复制
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"fullName" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];

在你的情况下,确保它不会影响性能。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12800062

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档