使用NSPredicate和tableview上的搜索框以及NSFetchedResultsController非常奇怪的结果
它应该基于匹配名称进行过滤...但是,如果我键入任何有效名称,我会得到一些不正确的结果。如果我输入任何全名,如“Mike Johnson”或“Kelly Michaels”,我总会得到“Angelo Smith”的过滤结果。
NSLog将显示 “名字CONTAINS [cd] \”Kelly Michaels \“”
然而,屏幕上显示的过滤结果只显示Angelo Smith?有任何想法如何解决这个问题?
如果您需要有关我正在做的事情的更多详细信息,我一直在使用此堆栈帖子中的解决方案 How to filter NSFetchedResultsController (CoreData) with UISearchDisplayController/UISearchBar
- (NSFetchedResultsController *)newFetchedResultsControllerWithSearch:(NSString *)searchString
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
NSPredicate *filterPredicate = nil;
/*
Set up the fetched results controller.
*/
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Staff" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSMutableArray *predicateArray = [NSMutableArray array];
if(searchString.length)
{
NSLog(@"here searchString is %@", searchString);
// your search predicate(s) are added to this array
[predicateArray addObject:[NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", searchString]];
// finally add the filter predicate for this view
NSLog(@"%@", predicateArray);
if(filterPredicate)
{
filterPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:filterPredicate, [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray], nil]];
}
else
{
filterPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray];
}
}
[fetchRequest setPredicate:filterPredicate];
...
答案 0 :(得分:2)
除非数据集发生变化,否则我不会在过滤时创建新的FRC。相反,只需更改谓词并执行另一次提取(在一个名为filterContentForSearchText的自定义方法中)
示例:
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[self filterContentForSearchText:searchText];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
searchBar.text = @"";
NSPredicate *predicate = nil;
[self.fetchedResultsController.fetchRequest setPredicate:predicate];
[self.fetchedResultsController.fetchRequest setFetchLimit:0]; // 0 is no limit
[searchBar resignFirstResponder];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
// Handle error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); //
}
[self.myTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
}
- (void)filterContentForSearchText:(NSString*)searchText
{
NSString *query = searchText;
if (query && query.length) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@ or department contains[cd] %@", query, query];
[self.fetchedResultsController.fetchRequest setPredicate:predicate];
[self.fetchedResultsController.fetchRequest setFetchLimit:100]; // I use 100 because of the large dataset I am working with (4500 records)
}
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
// Handle error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
[self.myTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self filterContentForSearchText:searchBar.text];
[searchBar resignFirstResponder];
}