Domanda

Qual è la migliore pratica per filtrare i dati NSFetchedResultsController ? devo reinizializzarlo ogni volta che cambia il testo della barra di ricerca?

Sto usando un UISearchDisplayControllers e sto implementando:

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

Thx.

È stato utile?

Soluzione

In che modo il codice di risposta di Guy è diverso dalla domanda? Per quanto posso immaginare, il metodo filterContentForSearchText: scope viene chiamato dai metodi shouldReload?

Comunque, ecco un codice simile che ho aggiunto nell'esempio CoreDataBooks per includere la ricerca. Aggiungi un controller di visualizzazione della ricerca in IB per l'esempio CoreDataBooks. Quindi ho aggiunto il codice a RootViewController.m come segue:

- (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. Per rispondere a Vivas, utilizzando un UISearchDisplayController crea automaticamente una nuova vista tabella per sovrapporre l'elenco filtrato. Puoi controllare quale tableView viene utilizzato come mostrato nei documenti, ma nella configurazione più semplice funziona solo perché fetchedResultsController mostra una versione filtrata nella vista tabella della ricerca o mostra tutti i dati nella vista tabella.

Altri suggerimenti

Apparentemente questo è un modo migliore:

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

 }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top