- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在使用来自 NSFetchedResults Controller 的混合、索引、可搜索结果集时遇到了一些问题。我将其设置为存储实体的索引 A-Z 第一个首字母,然后希望它显示数字第一个首字母(即 # 就像 UILocalizedIndexCollation 所做的那样)。
如果全名以数字开头,我已经编写了将 Artist 对象的“firstInitial”属性保存为 NSString @"#"的代码,并且我似乎已经在我的 UITableViewController 中使用了一半的代码自定义排序描述符。问题是它只在我退出/重新启动应用程序之前有效。
此时,抓取结果中的 # 部分出现在顶部。它会留在那里,直到我强制更改数据(添加/删除托管对象),然后搜索条目并清除搜索(使用 searchDisplayController)。此时,部分重新排序将开始,# 部分将移至底部...
我显然遗漏了什么/盯着同一个代码看得太久了。或者,还有一种我不知道/无法在 Google 上找到的更简单的方法!
如有任何帮助,我们将不胜感激!
谢谢
肖恩
我的 UITableViewController 的相关代码如下。
- (void)viewDidLoad
{
// ----------------------------------
// Various other view set up things in here....
// ...
// ...
// ----------------------------------
NSError *error;
if (![[self artistResultsController] performFetch:&error]) {
// Update to handle the error appropriately.
NSLog(@"Failed to fetch artists: %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
}
- (NSFetchedResultsController *)artistResultsController {
if (_artistResultsController != nil) {
return _artistResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Artist" inManagedObjectContext:_context];
[fetchRequest setEntity:entity];
NSSortDescriptor *initialSort = [[NSSortDescriptor alloc]
initWithKey:@"firstInitial"
ascending:YES
comparator:^(id obj1, id obj2) {
// Various number conditions for comparison - if it's a # initial, then it's a number
if (![obj1 isEqualToString:@"#"] && [obj2 isEqualToString:@"#"]) return NSOrderedAscending;
else if ([obj1 isEqualToString:@"#"] && ![obj2 isEqualToString:@"#"]) return NSOrderedDescending;
if ([obj1 isEqualToString:@"#"] && [obj2 isEqualToString:@"#"]) return NSOrderedSame;
// Else it's a string - compare it by localized region
return [obj1 localizedCaseInsensitiveCompare:obj2];
}];
NSSortDescriptor *nameSort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:initialSort, nameSort, nil]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:_context
sectionNameKeyPath:@"firstInitial"
cacheName:nil];
self.artistResultsController = theFetchedResultsController;
_artistResultsController.delegate = self;
[nameSort release];
[initialSort release];
[fetchRequest release];
[_artistResultsController release];
return _artistResultsController;}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return nil;
} else {
return [[[_artistResultsController sections] objectAtIndex:section] name];
}
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return nil;
} else {
return [[NSArray arrayWithObject:UITableViewIndexSearch] arrayByAddingObjectsFromArray:
[[UILocalizedIndexedCollation currentCollation] sectionIndexTitles]];
}
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return 0;
} else {
if (title == UITableViewIndexSearch) {
[tableView scrollRectToVisible:self.searchDisplayController.searchBar.frame animated:NO];
return -1;
}
else {
for (int i = [[_artistResultsController sections] count] -1; i >=0; i--) {
NSComparisonResult cr =
[title localizedCaseInsensitiveCompare:
[[[_artistResultsController sections] objectAtIndex:i] indexTitle]];
if (cr == NSOrderedSame || cr == NSOrderedDescending) {
return i;
}
}
return 0;
}
}
}
编辑:忘记提及 - 我的搜索过滤器在 fetchedResults Controller 上使用谓词,所以这会导致新的获取请求,就像这样
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
NSFetchRequest *aRequest = [_artistResultsController fetchRequest];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH[cd] %@", searchText];
// set predicate to the request
[aRequest setPredicate:predicate];
// save changes
NSError *error = nil;
if (![_artistResultsController performFetch:&error]) {
NSLog(@"Failed to filter artists: %@, %@", error, [error userInfo]);
abort();
}
}
最佳答案
我最终以不同的方式解决了这个问题。
当您还使用带有 SQLite 的 CoreData 作为后端存储时,SortDescriptors 似乎无法运行自定义排序。我尝试了一些东西;具有新比较方法的 NSString 类别,上面列出的比较 block ,并多次刷新表以尝试强制更新排序标准。
最后,我无法强制排序描述符进行初始排序,所以我更改了实现。我将名字以数字开头的艺术家的 firstInitial 属性设置为“zzzz”。这意味着 CoreData 将立即对其进行正确排序(最后是数字)。
完成此操作后,我对 titleForHeaderInSection 方法进行了硬编码,以在合适的情况下为标题返回 #,如下所示:
if ([[[[_artistResultsController sections] objectAtIndex:section] indexTitle] isEqualToString:@"zzzz"]) return [NSString stringWithString:@"#"];
return [[[_artistResultsController sections] objectAtIndex:section] indexTitle];
本质上,这意味着它将数字分类为“zzzz”分组,这应该是最后一个,我只是忽略该标题并说标题是 #。
不确定是否有更好的方法来执行此操作,但它将所有排序保留在 CoreData 中,从长远来看,这可能更高效/可扩展。
关于iphone - 来自 NSFetchedResultsController 的索引结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6011054/
我正在尝试使用具有混合语言数据的 FRC,并希望有一个部分索引。 从文档看来您应该能够覆盖 FRC - (NSString *)sectionIndexTitleForSectionName:(NSS
使用等效的 NSFetchRequest 重新创建 NSFetchedResultsController 时,为什么 [NSFetchedResultsController PerformFetch:
我正在尝试起草一个可重复使用的类,该类基本上可重复用于具有几乎相同实现的多个实体。基本上我将有几个 UIViewController,每个都包含 UIView,其中包含 UITableView 以及由
我有一个 iPhone 和一个 Android 应用程序。在 iPhone 上,我使用 NSFetchedResultsController 来管理我的 UITableView 的数据。目前我有很多数
NSFetchedResultsController 监视对正在跟踪的整个托管对象的更改。每当在当前上下文中修改任何属性时,例如 – controller:didChangeObject:atInde
自 1 个月以来,我一直在使用 NSFetchedResultsController 构建应用程序,并在 3.1.2 SDK 上测试该应用程序。问题是我一直在我的应用程序中到处使用 NSFetched
我有一个人物和宠物的数据库,具有一对多关系 人宠物 姓名 姓名 宠物>主人 我正在使用由核心数据支持的 UITableView 和 nsfetchedresultscontroller 来显示宠物列表
我有一个 NSFetchedResultsController,它在 TableView 中显示项目列表,包括关联实体的计数。当为此关联添加对象时(使用 addXXXObject),不会调用回调来通知
花了几个小时后,我发现无法在以下文章中由 SQLite 支持的 NSFetchedResultsController 中进行自定义排序。 NSFetchedResultsController cust
我设置了一个 NSFetchedResultsController 来填充 UITableView,基于我的“主”NSManagedObjectContext。 在计时器中,我不断地将对象添加到单独的
在我的应用程序中,我需要循环遍历核心数据中的所有实体,并且我正在使用 NSFetchedresultcontroller。 我现在正在这样做: NSArray *tempArray = [[NSArr
我正在开发我的第一个核心数据支持的应用程序,但无法弄清楚如何正确设置 NSFetchedResultsController。我有两个实体: /-----------\ /--------
我正在使用 NSFetchedResultsController 在 TableView 中显示项目: - (NSInteger)numberOfSectionsInTableView:(UITabl
我将 NSFetchedResultsController 放入我的代码中,这样我就可以对 TableView 数据进行很好的自动分段。 所以我正在运行测试以确保一切正常。我的持久存储中有一个 Boo
我如何使用带有翻译后的排序键和sectionKeyPath的NSFetchedResultsController? 问题:我在数据库中的属性“type”中有 ID,例如 typeA、typeB、typ
大家好 我的 CoreData 驱动应用程序有多个来自同一存储的数据 View ,并且全部使用 NSFetchedResultsController。目前,它们的 NSFetchedResultsCo
我想使用使用 bool 值设置的不同谓词从 NSFetchedResultsController 重新获取数据。如何刷新 NSFetchedResultsController 以获取一组新数据? -
核心数据在 NSManagedObjectContext 类中提供了“executeFetchRequest”方法,我们可以使用该方法从表中获取数据并以任何需要的方式使用它。 现在还有另一种方法,即使
我正在编写一个应用程序,一个屏幕上有两个表格。左表是文件夹列表,右表显示文件列表。当点击左侧的一行时,右侧表格将显示属于该文件夹的文件。 我正在使用 Core Data 进行存储。当文件夹的选择发生变
我有一个由 NSFetchedResultsController 管理的 TableView 。但是,我在查找或创建操作时遇到问题。当用户点击表格 View 的底部时,我正在向服务器查询另一批内容。如
我是一名优秀的程序员,十分优秀!