NSFetchedResultsController с поиском - PullRequest
       18

NSFetchedResultsController с поиском

17 голосов
/ 13 сентября 2009

Как лучше всего фильтровать данные NSFetchedResultsController? мне нужно повторно инициализировать его каждый раз, когда изменяется текст панели поиска?

Я использую UISearchDisplayControllers, и я реализую:

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

Thx.

Ответы [ 2 ]

17 голосов
/ 18 ноября 2009

Чем код ответа Гая отличается от вопроса? Насколько я могу догадаться, метод filterContentForSearchText: scope вызывается методами shouldReload?

В любом случае, вот некоторый похожий код, который я добавил в пример CoreDataBooks для включения поиска. Добавьте контроллер отображения поиска в IB для примера CoreDataBooks. Затем я добавил код в 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. Чтобы ответить на Vivas, используя UISearchDisplayController, он автоматически создает новое табличное представление для наложения отфильтрованного списка. Вы можете проверить, какой tableView используется, как показано в документации, но в простейшей настройке он работает просто потому, что fetchedResultsController либо показывает отфильтрованную версию в табличном представлении поиска, либо показывает все данные в табличном представлении.

8 голосов
/ 14 сентября 2009

По-видимому, это лучший способ:

- (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];

 }
...