2009-09-13 81 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