NSSortDescriptor问题 [英] NSSortDescriptor issue

查看:90
本文介绍了NSSortDescriptor问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在制作通讯录应用程序,其中我从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆