NSSortDescriptor问题 [英] NSSortDescriptor issue
问题描述
我在制作通讯录应用程序,其中我从AddressBook中提取名称,并将其存储在Core数据中,并使用 NSFetchedResultsController.However
在表上显示第一个索引和出现的部分是#后跟字母。但我想做它就像在本机联系人应用程序ie#index应该最后。
我使用以下 NSortDescriptor
:
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@fullNameascending:YES];
这里fullName是核心数据中的键
,它是通过连接名字和姓氏。
如果 fullName
不以字母开头,其段标识符为#,则段标识符是fullName的第一个字母。
我搜索过它,并在 NSortDescriptor
比较器中使用 NSDiacriticInsensitiveSearch
,但它没有工作。
这里是我的代码:
code> NSString * special = @\\\;
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:@sortNameascending:YES];
[self sectionIdentifier:sortName]
newContact是实体的对象。
$ b $返回#如果sortName以非字母开头,你可以在实体中存储一个额外的属性 sortName
,它是 fullName
(如果名称以字母开头,而< C> fullName
)。 < C>
是一个固定字符,比所有字母大。例如 NSString * special = @\\\;
if(fullName以字母开头)
sortName = fullName;
else
sortName = [special stringByAppendingString:fullName];
现在可以根据 sortName
如果 sortName
以特殊字符开头,则部分标识符将为#。
缺点是必须存储一个附加属性,其优点是您可以继续使用获取的结果控制器(只能使用持久属性进行排序)。
UPDATE
创建新条目时,您可以设置 sectionIdentifier
到字符的第一个字符,如果是字母,并且到特殊字符,否则:
NSString * special = @\\\;
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;
}
I am making a contact book App where I am fetching names from AddressBook and stored them in Core data and displayed the names on a table using NSFetchedResultsController.However
the first index and section that comes up is # followed by the alphabets. But I want to do it like it is in native contact app i.e. # index should come at last.
I used the following NSortDescriptor
:
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"fullName" ascending:YES ];
here "fullName" is the key
in core data which is made by concatenating first name and last name.
And the section identifier is the first letter of "fullName" if the fullName
doesn't start with alphabet, its section identifier is #.
I had searched about it and used NSDiacriticInsensitiveSearch
in the NSortDescriptor
comparator but it didn't worked. If any one has any idea then let me know.
Here goes my code:
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"];
And here is the sort descriptor:
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sortName" ascending:YES];
[self sectionIdentifier:sortName]
this method returns # if sortName starts with a non alphabet and else it returns the alphabet by which it starts.
newContact is the object of the entity.
You could store an additional attribute sortName
in the entity, which is fullName
if the name starts with a letter, and <C>fullName
otherwise. <C>
is a fixed character which is "greater" than all letters. For example
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 would be "#" if sortName
starts with the special character.
The disadvantage is that you have to store an additional attribute, the advantage is that you can continue to use a fetched results controller (which can use only persistent attributes for sorting).
UPDATE: It can actually be done a bit easier.
When you create a new entry, you set sectionIdentifier
to the first character of the name if it is a letter, and to the special character otherwise:
NSString *special = @"\uE000";
if ([[NSCharacterSet letterCharacterSet] characterIsMember:[contact.contactName characterAtIndex:0]]) {
contact.sectionIdentifier = [contact.contactName substringToIndex:1];
} else {
contact.sectionIdentifier = special;
}
The fetched results controller uses sectionIdentifier
for grouping and sorting the sections. Entries within 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 header #
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;
}
这篇关于NSSortDescriptor问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!