2009-09-13 84 views
17

过滤NSFetchedResultsController数据的最佳做法是什么? 每次搜索栏的文本更改时,是否需要重新初始化它?带搜索的NSFetchedResultsController

我使用的是UISearchDisplayControllers和我执行:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString; 

THX。

+0

你是如何最终处理表视图数据源方法,以便表视图将知道是否显示“过滤列表”? – CraigH 2009-10-06 20:37:47

+1

这里的答案是非常有帮助的 http://stackoverflow.com/questions/44712​​89/how-to-filter-nsfetchedresultscontroller-coredata-with-uisearchdisplaycontroll/4481896#4481896 – acecapades 2012-02-20 09:13:01

+0

以下是我所做的:http:// stackoverflow .com/questions/44712​​89/how-to-filter-nsfetchedresultscontroller-coredata -with-uisearchdisplaycontrolle/4856118#4856118 – 2011-01-31 22:06:55

回答

17

如何是盖伊的答案代码问题有什么不同?据我猜测,filterContentForSearchText:scope方法是由shouldReload方法调用的?

无论如何,下面是我在CoreDataBooks示例中添加的一些类似代码,以包含搜索。 CoreDataBooks示例在IB中添加Search Display Controller。然后我将代码添加到RootViewController.m中,如下所示:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { 
NSInteger searchOption = controller.searchBar.selectedScopeButtonIndex; 
return [self searchDisplayController:controller shouldReloadTableForSearchString:searchString searchScope:searchOption]; 
} 

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption { 
NSString* searchString = controller.searchBar.text; 
return [self searchDisplayController:controller shouldReloadTableForSearchString:searchString searchScope:searchOption]; 
} 

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString*)searchString searchScope:(NSInteger)searchOption { 

NSPredicate *predicate = nil; 
if ([searchString length]) 
    if (searchOption == 0) // full text, in my implementation. Other scope button titles are "Author", "Title" 
    predicate = [NSPredicate predicateWithFormat:@"title contains[cd] %@ OR author contains[cd] %@", searchString, searchString]; 
    else 
    // docs say keys are case insensitive, but apparently not so. 
    predicate = [NSPredicate predicateWithFormat:@"%K contains[cd] %@", [[controller.searchBar.scopeButtonTitles objectAtIndex:searchOption] lowercaseString], searchString]; 
[fetchedResultsController.fetchRequest setPredicate:predicate]; 

    NSError *error = nil; 
    if (![[self fetchedResultsController] performFetch:&error]) { 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
    }   

return YES; 
} 

PS。要使用UISearchDisplayController来回答Vivas,它会自动创建一个新的表格视图,用于覆盖已过滤的列表。您可以按照文档中所示检查正在使用哪个tableView,但是在最简单的设置中,它可以正常工作,因为fetchedResultsController在搜索的表视图中显示过滤版本或显示表视图中的所有数据。

+0

仍然奇怪的行为...对象确实得到过滤,但是当我向下滚动表视图时,它会给出一个异常,因为fetchController在特定索引处没有对象...什么可能是错误的?请帮忙 – 2012-09-18 09:57:23

+0

我想出了我的问题......当我得到过滤结果时,它们以相同方式显示在tableView中,当我滚动到行数X小于X的实际行数时......我应该做什么.. – 2012-09-18 11:14:28

8

Appearantly这是一个更好的办法:

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope 
{ 
    self.savedSearchTerm = searchText; 

    freshData = NO; 
    if (searchText !=nil) 
    { 
      NSPredicate *predicate =[NSPredicate predicateWithFormat:@"name contains[cd] %@", searchText]; 
      [fetchedResultsController.fetchRequest setPredicate:predicate]; 
    } 
    else 
    { 
      NSPredicate *predicate =[NSPredicate predicateWithFormat:@"All"]; 
      [fetchedResultsController.fetchRequest setPredicate:predicate]; 
    } 

    NSError *error = nil; 
    if (![[self fetchedResultsController] performFetch:&error]) { 
      // Handle error 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      exit(-1); // Fail 
    }   

    [self.tableView reloadData]; 

    // [searchBar resignFirstResponder]; 
    // [_shadeView setAlpha:0.0f]; 

} 
+29

exit(-1)有点苛刻。 – 0xced 2010-06-10 10:51:18

+5

appl文档说,不应该改变提取请求 - 他们特别说你不应该改变谓词。 – 2010-11-07 18:15:00

+1

@RogerNolan你确定吗?查看[NSFetchedResultsController类参考:修改提取请求](http://j.mp/z3W7QK)。这三个步骤对我来说工作得很好,我甚至修改了获取请求的谓词。 – ma11hew28 2012-01-21 22:49:16